Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
81204bd23a |
69
Makefile
69
Makefile
@ -1,62 +1,19 @@
|
||||
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
|
||||
obj-m += sharp.o
|
||||
sharp-objs += main.o drm_iface.o params_iface.o ioctl_iface.o
|
||||
|
||||
dtb-y += sharp-drm.dtbo
|
||||
export KROOT=/lib/modules/$(shell uname -r)/build
|
||||
|
||||
targets += $(dtbo-y)
|
||||
always := $(dtbo-y)
|
||||
all: modules sharp.dtbo
|
||||
|
||||
.PHONY: all clean install uninstall
|
||||
modules modules_install clean::
|
||||
@$(MAKE) -C $(KROOT) M=$(shell pwd) $@
|
||||
|
||||
# LINUX_DIR is set by Buildroot, but not if running manually
|
||||
ifeq ($(LINUX_DIR),)
|
||||
LINUX_DIR := /lib/modules/$(shell uname -r)/build
|
||||
endif
|
||||
modules_install:: sharp.dtbo
|
||||
@$(MAKE) -C $(KROOT) M=$(shell pwd) $@
|
||||
cp sharp.dtbo /boot/overlays
|
||||
|
||||
# BUILD_DIR is set by DKMS, but not if running manually
|
||||
ifeq ($(BUILD_DIR),)
|
||||
BUILD_DIR := .
|
||||
endif
|
||||
sharp.dtbo: sharp.dts
|
||||
dtc -@ -I dts -O dtb -o sharp.dtbo sharp.dts
|
||||
|
||||
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
|
||||
clean::
|
||||
rm -rf Module.symvers modules.order
|
||||
|
44
README.md
44
README.md
@ -2,50 +2,6 @@
|
||||
|
||||
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
|
||||
|
@ -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, vcom_setting);
|
||||
gpiod_set_value(panel->gpio_vcom, 1);
|
||||
|
||||
// Reschedule the timer
|
||||
mod_timer(&panel->vcom_timer, jiffies + msecs_to_jiffies(1000));
|
||||
@ -146,10 +146,12 @@ 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++) {
|
||||
@ -171,6 +173,14 @@ static void draw_indicators(struct sharp_memory_panel *panel, u8* buf, int width
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
@ -455,11 +465,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_drm",
|
||||
.name = "sharp_memory",
|
||||
.desc = "Sharp Memory LCD panel",
|
||||
.date = "20230713",
|
||||
.date = "20230526",
|
||||
.major = 1,
|
||||
.minor = 1,
|
||||
.minor = 0,
|
||||
};
|
||||
|
||||
int drm_probe(struct spi_device *spi)
|
||||
@ -589,25 +599,16 @@ void drm_remove(struct spi_device *spi)
|
||||
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_clip_rect dirty_rect;
|
||||
struct drm_rect dirty_rect;
|
||||
|
||||
if (!g_panel) {
|
||||
if (!g_panel || !g_panel->fb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -616,15 +617,15 @@ int drm_refresh(void)
|
||||
dirty_rect.x2 = g_panel->fb->width;
|
||||
dirty_rect.y1 = 0;
|
||||
dirty_rect.y2 = g_panel->fb->height;
|
||||
return force_redraw(g_panel->fb, &dirty_rect);
|
||||
|
||||
return sharp_memory_fb_dirty(g_panel->fb, &dirty_rect);
|
||||
}
|
||||
|
||||
int drm_set_indicator(size_t idx, char c)
|
||||
{
|
||||
struct drm_clip_rect dirty_rect;
|
||||
|
||||
if (!g_panel || !g_panel->fb || !g_panel->fb->funcs
|
||||
|| !g_panel->fb->funcs->dirty) {
|
||||
struct drm_rect dirty_rect;
|
||||
printk(KERN_INFO "Setting indicator %zu to %c\n", idx, c);
|
||||
if (!g_panel || !g_panel->fb) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -634,10 +635,12 @@ int drm_set_indicator(size_t idx, char c)
|
||||
}
|
||||
g_panel->indicators[idx] = c;
|
||||
|
||||
// Refresh indicator portion of framebuffer
|
||||
dirty_rect.x1 = 0;
|
||||
// Refresh framebuffer
|
||||
dirty_rect.x1 = 0;//g_panel->fb->width - INDICATORS_WIDTH;
|
||||
dirty_rect.x2 = g_panel->fb->width;
|
||||
dirty_rect.y1 = 0;
|
||||
dirty_rect.y2 = INDICATOR_HEIGHT;
|
||||
return force_redraw(g_panel->fb, &dirty_rect);
|
||||
|
||||
printk(KERN_INFO "Refreshing framebuffer\n");
|
||||
return sharp_memory_fb_dirty(g_panel->fb, &dirty_rect);
|
||||
}
|
@ -49,7 +49,7 @@ static void sharp_memory_shutdown(struct spi_device *spi)
|
||||
|
||||
static struct spi_driver sharp_memory_spi_driver = {
|
||||
.driver = {
|
||||
.name = "sharp-drm",
|
||||
.name = "sharp",
|
||||
},
|
||||
.probe = sharp_memory_probe,
|
||||
.remove = sharp_memory_remove,
|
||||
@ -57,7 +57,6 @@ 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");
|
@ -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(indicators, "0 for no indicators, 1 for indicators");
|
||||
MODULE_PARM_DESC(mono_invert, "0 for no indicators, 1 for indicators");
|
||||
|
||||
int params_probe(void)
|
||||
{
|
@ -43,8 +43,8 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
sharp_drm: sharp_drm@0{
|
||||
compatible = "sharp-drm";
|
||||
sharp: sharp@0{
|
||||
compatible = "sharp";
|
||||
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 = <4000000>;
|
||||
spi-max-frequency = <8000000>;
|
||||
buswidth = <8>;
|
||||
debug = <0>;
|
||||
};
|
Loading…
Reference in New Issue
Block a user