From 15cf5667c9508d18808e0edf95acbff0313ef954 Mon Sep 17 00:00:00 2001 From: Serge Schneider Date: Mon, 17 Aug 2015 18:06:16 +0100 Subject: [PATCH 161/203] rpisense-fb: add low-light mode and gamma control --- drivers/video/fbdev/rpisense-fb.c | 68 +++++++++++++++++++++++++++++--- include/linux/mfd/rpisense/framebuffer.h | 6 ++- 2 files changed, 68 insertions(+), 6 deletions(-) --- a/drivers/video/fbdev/rpisense-fb.c +++ b/drivers/video/fbdev/rpisense-fb.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -26,22 +27,35 @@ #include #include +static bool lowlight; +module_param(lowlight, bool, 0); +MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third"); + struct rpisense *rpisense; struct rpisense_fb_param { char __iomem *vmem; u8 *vmem_work; u32 vmemsize; - u8 gamma[32]; + u8 *gamma; }; +static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, + 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}; + +static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, + 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,}; + +static u8 gamma_user[32]; + static struct rpisense_fb_param rpisense_fb_param = { .vmem = NULL, .vmemsize = 128, - .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, - 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, - 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}, + .gamma = gamma_default, }; static struct fb_deferred_io rpisense_fb_defio; @@ -127,6 +141,46 @@ static struct fb_deferred_io rpisense_fb .deferred_io = rpisense_fb_deferred_io, }; +static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case SENSEFB_FBIOGET_GAMMA: + if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma, + sizeof(u8[32]))) + return -EFAULT; + return 0; + case SENSEFB_FBIOSET_GAMMA: + if (copy_from_user(gamma_user, (void __user *)arg, + sizeof(u8[32]))) + return -EFAULT; + rpisense_fb_param.gamma = gamma_user; + schedule_delayed_work(&info->deferred_work, + rpisense_fb_defio.delay); + return 0; + case SENSEFB_FBIORESET_GAMMA: + switch (arg) { + case 0: + rpisense_fb_param.gamma = gamma_default; + break; + case 1: + rpisense_fb_param.gamma = gamma_low; + break; + case 2: + rpisense_fb_param.gamma = gamma_user; + break; + default: + return -EINVAL; + } + schedule_delayed_work(&info->deferred_work, + rpisense_fb_defio.delay); + break; + default: + return -EINVAL; + } + return 0; +} + static struct fb_ops rpisense_fb_ops = { .owner = THIS_MODULE, .fb_read = fb_sys_read, @@ -134,6 +188,7 @@ static struct fb_ops rpisense_fb_ops = { .fb_fillrect = rpisense_fb_fillrect, .fb_copyarea = rpisense_fb_copyarea, .fb_imageblit = rpisense_fb_imageblit, + .fb_ioctl = rpisense_fb_ioctl, }; static int rpisense_fb_probe(struct platform_device *pdev) @@ -171,6 +226,9 @@ static int rpisense_fb_probe(struct plat info->screen_base = rpisense_fb_param.vmem; info->screen_size = rpisense_fb_param.vmemsize; + if (lowlight) + rpisense_fb_param.gamma = gamma_low; + fb_deferred_io_init(info); ret = register_framebuffer(info); --- a/include/linux/mfd/rpisense/framebuffer.h +++ b/include/linux/mfd/rpisense/framebuffer.h @@ -16,7 +16,11 @@ #ifndef __LINUX_RPISENSE_FB_H_ #define __LINUX_RPISENSE_FB_H_ -#include +#define SENSEFB_FBIO_IOC_MAGIC 0xF1 + +#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0) +#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1) +#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2) struct rpisense;