Remove shutdown

This commit is contained in:
Andrew D'Angelo 2023-06-28 22:55:12 -05:00
parent 0e559597dd
commit e2a81f736b
9 changed files with 127 additions and 42 deletions

View File

@ -33,6 +33,8 @@
#include "ioctl_iface.h" #include "ioctl_iface.h"
#include "drm_iface.h" #include "drm_iface.h"
#include "indicators.h"
#define GPIO_DISP 22 #define GPIO_DISP 22
#define GPIO_SCS 8 #define GPIO_SCS 8
#define GPIO_VCOM 23 #define GPIO_VCOM 23
@ -57,6 +59,8 @@ struct sharp_memory_panel {
struct spi_transfer *spi_3_xfers; struct spi_transfer *spi_3_xfers;
unsigned char *cmd_buf; unsigned char *cmd_buf;
unsigned char *trailer_buf; unsigned char *trailer_buf;
char indicators[MAX_INDICATORS];
}; };
static struct sharp_memory_panel* g_panel = NULL; static struct sharp_memory_panel* g_panel = NULL;
@ -136,6 +140,47 @@ static int sharp_memory_spi_write_tagged_lines(struct sharp_memory_panel *panel,
return rc; return rc;
} }
static void draw_indicators(struct sharp_memory_panel *panel, u8* buf, int width,
struct drm_rect const* clip)
{
int i, dx, dy, sx, sy;
u8 const* ind = NULL;
for (i = 0; i < MAX_INDICATORS; i++) {
// Get indicator pixels
ind = indicator_for(panel->indicators[i]);
if (!ind) {
continue;
}
// Draw indicator pixels
for (sy = 0; sy < INDICATOR_HEIGHT; sy++) {
if (sy < clip->y1) {
continue;
} else if (clip->y2 <= sy) {
break;
}
dy = sy - clip->y1;
for (sx = 0; sx < INDICATOR_WIDTH; sx++) {
if (sx < clip->x1) {
continue;
} else if (clip->x2 <= sx) {
break;
}
dx = (width - ((i + 1) * INDICATOR_WIDTH) + sx) - clip->x1;
buf[dy * (clip->x2 - clip->x1) + dx] = ind[sy * INDICATOR_HEIGHT + sx];
}
}
}
}
static size_t sharp_memory_gray8_to_mono_tagged(u8 *buf, int width, int height, int y0) static size_t sharp_memory_gray8_to_mono_tagged(u8 *buf, int width, int height, int y0)
{ {
int line, b8, b1; int line, b8, b1;
@ -189,8 +234,8 @@ static size_t sharp_memory_gray8_to_mono_tagged(u8 *buf, int width, int height,
// Use DMA to get grayscale representation, then convert to mono // Use DMA to get grayscale representation, then convert to mono
// with line number and trailer tags suitable for multi-line write // with line number and trailer tags suitable for multi-line write
// Output is stored in `buf`, which must be at least W*H bytes // Output is stored in `buf`, which must be at least W*H bytes
static int sharp_memory_clip_mono_tagged(size_t* result_len, u8* buf, static int sharp_memory_clip_mono_tagged(struct sharp_memory_panel* panel, size_t* result_len,
struct drm_framebuffer *fb, struct drm_rect const* clip) u8* buf, struct drm_framebuffer *fb, struct drm_rect const* clip)
{ {
int rc; int rc;
struct drm_gem_dma_object *dma_obj; struct drm_gem_dma_object *dma_obj;
@ -209,11 +254,17 @@ static int sharp_memory_clip_mono_tagged(size_t* result_len, u8* buf,
iosys_map_set_vaddr(&dst, buf); iosys_map_set_vaddr(&dst, buf);
iosys_map_set_vaddr(&vmap, dma_obj->vaddr); iosys_map_set_vaddr(&vmap, dma_obj->vaddr);
// DMA `clip` into `buf` and convert to 8-bit grayscale // DMA `clip` into `buf` and convert to 8-bit grayscale
drm_fb_xrgb8888_to_gray8(&dst, NULL, &vmap, fb, clip); drm_fb_xrgb8888_to_gray8(&dst, NULL, &vmap, fb, clip);
// End DMA area // End DMA area
drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
// Add indicators if in range
if ((clip->x1 >= (fb->width - INDICATORS_WIDTH))
&& (clip->y1 < INDICATOR_HEIGHT)) {
draw_indicators(panel, buf, fb->width, clip);
}
// Convert in-place from 8-bit grayscale to mono // Convert in-place from 8-bit grayscale to mono
*result_len = sharp_memory_gray8_to_mono_tagged(buf, *result_len = sharp_memory_gray8_to_mono_tagged(buf,
(clip->x2 - clip->x1), (clip->y2 - clip->y1), clip->y1); (clip->x2 - clip->x1), (clip->y2 - clip->y1), clip->y1);
@ -246,7 +297,7 @@ static int sharp_memory_fb_dirty(struct drm_framebuffer *fb,
} }
// Convert `clip` from framebuffer to mono with line number tags // Convert `clip` from framebuffer to mono with line number tags
rc = sharp_memory_clip_mono_tagged(&buf_len, panel->buf, fb, &clip); rc = sharp_memory_clip_mono_tagged(panel, &buf_len, panel->buf, fb, &clip);
if (rc) { if (rc) {
goto out_exit; goto out_exit;
} }
@ -419,7 +470,7 @@ int drm_probe(struct spi_device *spi)
struct device *dev; struct device *dev;
struct sharp_memory_panel *panel; struct sharp_memory_panel *panel;
struct drm_device *drm; struct drm_device *drm;
int ret; int ret, i;
printk(KERN_INFO "sharp_memory: entering drm_probe\n"); printk(KERN_INFO "sharp_memory: entering drm_probe\n");
@ -458,6 +509,9 @@ int drm_probe(struct spi_device *spi)
panel->mode = mode; panel->mode = mode;
panel->width = mode->hdisplay; panel->width = mode->hdisplay;
panel->height = mode->vdisplay; panel->height = mode->vdisplay;
for (i = 0; i < MAX_INDICATORS; i++) {
panel->indicators[i] = '\0';
}
// Allocate reused heap buffers suitable for SPI source // Allocate reused heap buffers suitable for SPI source
panel->buf = devm_kzalloc(dev, panel->width * panel->height, GFP_KERNEL); panel->buf = devm_kzalloc(dev, panel->width * panel->height, GFP_KERNEL);
@ -510,39 +564,57 @@ int drm_probe(struct spi_device *spi)
void drm_remove(struct spi_device *spi) void drm_remove(struct spi_device *spi)
{ {
struct drm_device *drm; struct drm_device *drm;
struct sharp_memory_panel *panel;
printk(KERN_DEBUG "sharp_memory: drm_remove\n"); printk(KERN_INFO "sharp_memory: drm_remove\n");
// Clear global panel // Clear global panel
g_panel = NULL; g_panel = NULL;
// Get DRM and panel device from SPI // Get DRM and panel device from SPI
drm = spi_get_drvdata(spi); drm = spi_get_drvdata(spi);
panel = drm_to_panel(drm);
drm_dev_unplug(drm); drm_dev_unplug(drm);
drm_atomic_helper_shutdown(drm); drm_atomic_helper_shutdown(drm);
} }
void drm_shutdown(struct spi_device *spi)
{
drm_atomic_helper_shutdown(spi_get_drvdata(spi));
}
int drm_refresh(void) int drm_refresh(void)
{ {
struct drm_rect dirty_rect; struct drm_rect dirty_rect;
if (g_panel && g_panel->fb) { if (!g_panel || !g_panel->fb) {
return 0;
// Refresh framebuffer
dirty_rect.x1 = 0;
dirty_rect.x2 = g_panel->fb->width;
dirty_rect.y1 = 0;
dirty_rect.y2 = g_panel->fb->height;
return sharp_memory_fb_dirty(g_panel->fb, &dirty_rect);
} }
return 0; g_panel->indicators[0] = '^';
// Refresh framebuffer
dirty_rect.x1 = 0;
dirty_rect.x2 = g_panel->fb->width;
dirty_rect.y1 = 0;
dirty_rect.y2 = g_panel->fb->height;
return sharp_memory_fb_dirty(g_panel->fb, &dirty_rect);
}
int drm_set_indicator(size_t idx, char c)
{
struct drm_rect dirty_rect;
if (!g_panel || !g_panel->fb) {
return -1;
}
// Set indicator
if (idx >= MAX_INDICATORS) {
return -1;
}
g_panel->indicators[idx] = c;
// Refresh framebuffer
dirty_rect.x1 = g_panel->fb->width - INDICATORS_WIDTH;
dirty_rect.x2 = g_panel->fb->width;
dirty_rect.y1 = 0;
dirty_rect.y2 = INDICATOR_HEIGHT;
return sharp_memory_fb_dirty(g_panel->fb, &dirty_rect);
} }

View File

@ -27,7 +27,6 @@
int drm_probe(struct spi_device *spi); int drm_probe(struct spi_device *spi);
void drm_remove(struct spi_device *spi); void drm_remove(struct spi_device *spi);
void drm_shutdown(struct spi_device *spi);
int drm_refresh(void); int drm_refresh(void);

31
indicators.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef INDICATORS_H_
#define INDICATORS_H_
#define MAX_INDICATORS 6
#define INDICATOR_WIDTH 8
#define INDICATOR_HEIGHT 8
#define INDICATORS_WIDTH (INDICATOR_WIDTH * MAX_INDICATORS)
static u8 const ind_shift[] =
{ 0, 0, 0, 0xff, 0xff, 0, 0, 0
, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0
, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0
, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
, 0, 0, 0, 0xff, 0xff, 0, 0, 0
, 0, 0, 0, 0xff, 0xff, 0, 0, 0
, 0, 0, 0, 0xff, 0xff, 0, 0, 0
, 0, 0, 0, 0xff, 0xff, 0, 0, 0
};
static u8 const* indicator_for(char c)
{
switch (c) {
case '^': return ind_shift;
default:
return NULL;
}
}
#endif

View File

@ -11,8 +11,3 @@ void ioctl_remove(void)
{ {
return; return;
} }
void ioctl_shutdown(void)
{
return;
}

View File

@ -3,6 +3,5 @@
int ioctl_probe(void); int ioctl_probe(void);
void ioctl_remove(void); void ioctl_remove(void);
void ioctl_shutdown(void);
#endif #endif

4
main.c
View File

@ -44,9 +44,7 @@ static void sharp_memory_remove(struct spi_device *spi)
static void sharp_memory_shutdown(struct spi_device *spi) static void sharp_memory_shutdown(struct spi_device *spi)
{ {
ioctl_shutdown(); sharp_memory_remove(spi);
params_shutdown();
drm_shutdown(spi);
} }
static struct spi_driver sharp_memory_spi_driver = { static struct spi_driver sharp_memory_spi_driver = {

View File

@ -46,8 +46,3 @@ void params_remove(void)
{ {
return; return;
} }
void params_shutdown(void)
{
return;
}

View File

@ -6,6 +6,5 @@ extern int g_param_mono_invert;
int params_probe(void); int params_probe(void);
void params_remove(void); void params_remove(void);
void params_shutdown(void);
#endif #endif

View File

@ -31,7 +31,6 @@
__overlay__ { __overlay__ {
sharp_pins: sharp_pins { sharp_pins: sharp_pins {
brcm,pins = <23 22>; brcm,pins = <23 22>;
/* brcm,pins = <9 23>; */ /* <- older revision */
brcm,function = <1 1>; /* out */ brcm,function = <1 1>; /* out */
}; };
}; };
@ -50,12 +49,10 @@
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&sharp_pins>; pinctrl-0 = <&sharp_pins>;
spi-cs-high = <1>; spi-cs-high = <1>;
spi-max-frequency = <2000000>; spi-max-frequency = <8000000>;
buswidth = <8>; buswidth = <8>;
debug = <0>; debug = <0>;
}; };
}; };
}; };
}; };