Compare commits

...

23 Commits

Author SHA1 Message Date
Andrew D'Angelo
d1c30a9be5 Bump version for vcom fix 2023-09-18 17:16:10 -05:00
Andrew D'Angelo
2e0bde76a4
Merge pull request #5 from imnotjames/patch-1
fix: actually set vcom gpio value
2023-09-17 09:39:30 -05:00
James Ward
575a8aac1f
fix: actually set vcom gpio value
this was hard coded to always set the vcom to 1 when instead it's supposed to be alternating on and off
2023-09-09 19:57:26 -04:00
Andrew D'Angelo
8bdc22653f Move Buildroot scripts out of repo 2023-08-21 16:20:05 -05:00
Andrew D'Angelo
261d49b489 Check framebuffer function struct 2023-08-20 08:06:23 -05:00
Andrew D'Angelo
ec8b1613fe Change refresh to 400MHz 2023-08-19 16:56:49 -05:00
Andrew D'Angelo
1d9025debd Update readme with removal instructions 2023-08-19 12:19:01 -05:00
Andrew D'Angelo
f35bcc9045 Rename Sharp DRM driver 2023-08-12 19:01:24 -05:00
Andrew D'Angelo
f478e5f9b3 Rename to sharp-drm 2023-08-12 18:45:02 -05:00
Andrew D'Angelo
b688100bb7 Rename to sharp-drm 2023-08-12 18:41:48 -05:00
Andrew D'Angelo
356f882e5a Update Buildroot Makefile path 2023-08-10 19:51:08 -05:00
Andrew D'Angelo
a2f868c469 Update buildroot script 2023-08-05 18:54:23 -05:00
Andrew D'Angelo
86c79f407b Add section header to boot config 2023-08-05 09:49:22 -05:00
Andrew D'Angelo
d57ad7688b Update readme 2023-08-04 21:21:10 -05:00
Andrew D'Angelo
5f9ebd3c86 Handle manual build with Makefile 2023-08-04 20:22:30 -05:00
Andrew D'Angelo
8d69debbcb Buildroot included 2023-08-04 19:22:22 -05:00
Andrew D'Angelo
0f82af168d Fix refresh 2023-07-13 18:14:46 -05:00
Andrew D'Angelo
a123a82562
Use GPIO descriptor interface
Instead of hardcoded GPIO pin numbers
2023-07-11 19:25:43 -05:00
James Ward
c8095e4f59
fix: drop spurious scs & fix missing semicolon 2023-07-11 20:14:16 -04:00
Andrew D'Angelo
ed690942e8
Merge pull request #1 from imnotjames/drm-fix-param-name
fix: attach correct description to indicators param
2023-07-05 11:41:39 -05:00
Andrew D'Angelo
e5764b9cd9
Temporarily disable indicators 2023-07-05 11:40:43 -05:00
Andrew D'Angelo
2b45f0f873 Remove debug output 2023-07-04 09:07:10 -05:00
James Ward
adaab3e1c1
fix: attach correct description to indicators param 2023-06-30 13:20:51 -04:00
11 changed files with 133 additions and 45 deletions

View File

@ -1,12 +1,62 @@
obj-m += sharp.o
sharp-objs += main.o drm_iface.o params_iface.o ioctl_iface.o
obj-m += sharp-drm.o
sharp-drm-objs += src/main.o src/drm_iface.o src/params_iface.o src/ioctl_iface.o
ccflags-y := -g -std=gnu99 -Wno-declaration-after-statement
export KROOT=/lib/modules/$(shell uname -r)/build
dtb-y += sharp-drm.dtbo
all: modules
targets += $(dtbo-y)
always := $(dtbo-y)
modules modules_install clean::
@$(MAKE) -C $(KROOT) M=$(shell pwd) $@
.PHONY: all clean install uninstall
clean::
rm -rf Module.symvers modules.order
# LINUX_DIR is set by Buildroot, but not if running manually
ifeq ($(LINUX_DIR),)
LINUX_DIR := /lib/modules/$(shell uname -r)/build
endif
# BUILD_DIR is set by DKMS, but not if running manually
ifeq ($(BUILD_DIR),)
BUILD_DIR := .
endif
BOOT_CONFIG_LINE := dtoverlay=sharp-drm
BOOT_CMDLINE_ADD := console=tty2 fbcon=font:VGA8x8 fbcon=map:10
all:
$(MAKE) -C '$(LINUX_DIR)' M='$(shell pwd)'
install_modules:
$(MAKE) -C '$(LINUX_DIR)' M='$(shell pwd)' modules_install
# Rebuild dependencies
depmod -A
install: install_modules install_aux
# Separate rule to be called from DKMS
install_aux:
# Install device tree overlay
install -D -m 0644 $(BUILD_DIR)/sharp-drm.dtbo /boot/overlays/
# Add configuration line if it wasn't already there
grep -qxF '$(BOOT_CONFIG_LINE)' /boot/config.txt \
|| printf '[all]\ndtparam=spi=on\n$(BOOT_CONFIG_LINE)\n' >> /boot/config.txt
# Add auto-load module line if it wasn't already there
grep -qxF 'sharp-drm' /etc/modules \
|| echo 'sharp-drm' >> /etc/modules
# Configure fbcon for display
grep -qxF '$(BOOT_CMDLINE_ADD)' /boot/cmdline.txt \
|| sed -i.save 's/$$/ $(BOOT_CMDLINE_ADD)/' /boot/cmdline.txt
# Rebuild dependencies
depmod -A
uninstall:
# Remove fbcon configuration and create a backup file
sed -i.save 's/ $(BOOT_CMDLINE_ADD)//' /boot/cmdline.txt
# Remove auto-load module line and create a backup file
sed -i.save '/sharp-drm/d' /etc/modules
# Remove configuration line and create a backup file
sed -i.save '/$(BOOT_CONFIG_LINE)/d' /boot/config.txt
# Remove device tree overlay
rm -f /boot/overlays/sharp-drm.dtbo
clean:
$(MAKE) -C '$(LINUX_DIR)' M='$(shell pwd)' clean

View File

@ -2,6 +2,50 @@
DRM kernel driver for 2.7" 400x240 Sharp memory LCD panel.
## Cleaning old drivers
The `bbqX0kbd` driver has been renamed to `beepy-kbd`, and `sharp` to `sharp-drm`.
Driver packages will detect if one of these old modules is installed and cancel installation of the package.
Remove the following files:
* `/lib/modules/<uname>/extra/bbqX0kbd.ko*`
* `/lib/modules/<uname>/extra/sharp.ko*`
* `/boot/overlays/i2c-bbqX0kbd.dtbo`
* `/boot/overlays/sharp.dtbo`
Rebuild the module list:
* `depmod -a`
Remove the following lines from `/boot/config.txt`:
* `dtoverlay=bbqX0kbd,irq_pin=4`
* `dtoverlay=sharp`
Remove the following lines from `/etc/modules`:
* `bbqX0kbd`
* `sharp`
## Installation
Install the Linux kernel headers
sudo apt-get install raspberrypi-kernel-headers
To build, install, and enable the kernel module:
make
sudo make install
To remove:
sudo make uninstall
## [Original fbdev module readme with pinouts and build instructions](https://github.com/w4ilun/Sharp-Memory-LCD-Kernel-Driver/blob/master/README.md)
## References

View File

@ -43,8 +43,8 @@
#address-cells = <1>;
#size-cells = <0>;
sharp: sharp@0{
compatible = "sharp";
sharp_drm: sharp_drm@0{
compatible = "sharp-drm";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&sharp_pins>;
@ -53,7 +53,7 @@
disp-gpios = <&gpio 22 0>;
spi-cs-high = <1>;
spi-max-frequency = <8000000>;
spi-max-frequency = <4000000>;
buswidth = <8>;
debug = <0>;
};

View File

@ -77,7 +77,7 @@ static void vcom_timer_callback(struct timer_list *t)
// Toggle the GPIO pin
vcom_setting = (vcom_setting) ? 0 : 1;
gpiod_set_value(panel->gpio_vcom, 1);
gpiod_set_value(panel->gpio_vcom, vcom_setting);
// Reschedule the timer
mod_timer(&panel->vcom_timer, jiffies + msecs_to_jiffies(1000));
@ -146,12 +146,10 @@ static void draw_indicators(struct sharp_memory_panel *panel, u8* buf, int width
for (i = 0; i < MAX_INDICATORS; i++) {
// Get indicator pixels
printk(KERN_INFO "Indicator %d: %d\n", i, panel->indicators[i]);
ind = indicator_for(panel->indicators[i]);
if (!ind) {
continue;
}
printk(KERN_INFO "Drawing indicator for %c\n", panel->indicators[i]);
// Draw indicator pixels
for (sy = 0; sy < INDICATOR_HEIGHT; sy++) {
@ -173,14 +171,6 @@ printk(KERN_INFO "Drawing indicator for %c\n", panel->indicators[i]);
}
dx = (width - ((i + 1) * INDICATOR_WIDTH) + sx) - clip->x1;
printk(KERN_INFO "(%d, %d = %d) <- (%d, %d = %d) = %x\n",
dx, dy,
dy * (clip->x2 - clip->x1) + dx,
sx, sy,
sy * INDICATOR_HEIGHT + sx,
ind[sy * INDICATOR_HEIGHT + sx]
);
buf[dy * (clip->x2 - clip->x1) + dx] = ind[sy * INDICATOR_HEIGHT + sx];
}
}
@ -351,10 +341,6 @@ static void sharp_memory_pipe_enable(struct drm_simple_display_pipe *pipe,
}
// Power up sequence
if (panel->gpio_scs)
{
gpiod_set_value(panel->gpio_scs, 0);
}
gpiod_set_value(panel->gpio_disp, 1);
gpiod_set_value(panel->gpio_vcom, 0);
usleep_range(5000, 10000);
@ -469,11 +455,11 @@ static const struct drm_driver sharp_memory_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops = &sharp_memory_fops,
DRM_GEM_DMA_DRIVER_OPS_VMAP,
.name = "sharp_memory",
.name = "sharp_drm",
.desc = "Sharp Memory LCD panel",
.date = "20230526",
.date = "20230713",
.major = 1,
.minor = 0,
.minor = 1,
};
int drm_probe(struct spi_device *spi)
@ -598,21 +584,30 @@ void drm_remove(struct spi_device *spi)
// Clean up the GPIO descriptors
dev = &spi->dev;
panel = drm_to_panel(drm)
panel = drm_to_panel(drm);
devm_gpiod_put(dev, panel->gpio_disp);
devm_gpiod_put(dev, panel->gpio_vcom);
drm_dev_unplug(drm);
drm_atomic_helper_shutdown(drm);
}
static int force_redraw(struct drm_framebuffer* fb, struct drm_clip_rect* dirty_rect)
{
if (!fb || !fb->funcs->dirty) {
return -1;
}
// Call framebuffer region update handler
return fb->funcs->dirty(fb, NULL, 0, 0, dirty_rect, 1);
}
int drm_refresh(void)
{
struct drm_rect dirty_rect;
struct drm_clip_rect dirty_rect;
if (!g_panel || !g_panel->fb) {
if (!g_panel) {
return 0;
}
@ -621,15 +616,15 @@ int drm_refresh(void)
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 force_redraw(g_panel->fb, &dirty_rect);
}
int drm_set_indicator(size_t idx, char c)
{
struct drm_rect dirty_rect;
printk(KERN_INFO "Setting indicator %zu to %c\n", idx, c);
if (!g_panel || !g_panel->fb) {
struct drm_clip_rect dirty_rect;
if (!g_panel || !g_panel->fb || !g_panel->fb->funcs
|| !g_panel->fb->funcs->dirty) {
return -1;
}
@ -639,12 +634,10 @@ printk(KERN_INFO "Setting indicator %zu to %c\n", idx, c);
}
g_panel->indicators[idx] = c;
// Refresh framebuffer
dirty_rect.x1 = 0;//g_panel->fb->width - INDICATORS_WIDTH;
// Refresh indicator portion of framebuffer
dirty_rect.x1 = 0;
dirty_rect.x2 = g_panel->fb->width;
dirty_rect.y1 = 0;
dirty_rect.y2 = INDICATOR_HEIGHT;
printk(KERN_INFO "Refreshing framebuffer\n");
return sharp_memory_fb_dirty(g_panel->fb, &dirty_rect);
return force_redraw(g_panel->fb, &dirty_rect);
}

View File

@ -49,7 +49,7 @@ static void sharp_memory_shutdown(struct spi_device *spi)
static struct spi_driver sharp_memory_spi_driver = {
.driver = {
.name = "sharp",
.name = "sharp-drm",
},
.probe = sharp_memory_probe,
.remove = sharp_memory_remove,
@ -57,6 +57,7 @@ static struct spi_driver sharp_memory_spi_driver = {
};
module_spi_driver(sharp_memory_spi_driver);
MODULE_VERSION("1.1");
MODULE_DESCRIPTION("Sharp Memory LCD DRM driver");
MODULE_AUTHOR("Andrew D'Angelo");
MODULE_LICENSE("GPL");

View File

@ -39,7 +39,7 @@ module_param_cb(mono_invert, &u8_param_ops, &g_param_mono_invert, 0660);
MODULE_PARM_DESC(mono_invert, "0 for no inversion, 1 for inversion");
module_param_cb(indicators, &u8_param_ops, &g_param_indicators, 0660);
MODULE_PARM_DESC(mono_invert, "0 for no indicators, 1 for indicators");
MODULE_PARM_DESC(indicators, "0 for no indicators, 1 for indicators");
int params_probe(void)
{