|
19 | 19 | #include <linux/string.h>
|
20 | 20 | #include <linux/mm.h>
|
21 | 21 | #include <linux/slab.h>
|
| 22 | +#include <linux/uaccess.h> |
22 | 23 | #include <linux/delay.h>
|
23 | 24 | #include <linux/fb.h>
|
24 | 25 | #include <linux/init.h>
|
25 | 26 |
|
26 | 27 | #include <linux/mfd/rpisense/framebuffer.h>
|
27 | 28 | #include <linux/mfd/rpisense/core.h>
|
28 | 29 |
|
| 30 | +static bool lowlight; |
| 31 | +module_param(lowlight, bool, 0); |
| 32 | +MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third"); |
| 33 | + |
29 | 34 | struct rpisense *rpisense;
|
30 | 35 |
|
31 | 36 | struct rpisense_fb_param {
|
32 | 37 | char __iomem *vmem;
|
33 | 38 | u8 *vmem_work;
|
34 | 39 | u32 vmemsize;
|
35 |
| - u8 gamma[32]; |
| 40 | + u8 *gamma; |
36 | 41 | };
|
37 | 42 |
|
| 43 | +static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, |
| 44 | + 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 45 | + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, |
| 46 | + 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}; |
| 47 | + |
| 48 | +static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, |
| 49 | + 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, |
| 50 | + 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, |
| 51 | + 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,}; |
| 52 | + |
| 53 | +static u8 gamma_user[32]; |
| 54 | + |
38 | 55 | static struct rpisense_fb_param rpisense_fb_param = {
|
39 | 56 | .vmem = NULL,
|
40 | 57 | .vmemsize = 128,
|
41 |
| - .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, |
42 |
| - 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, |
43 |
| - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11, |
44 |
| - 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,}, |
| 58 | + .gamma = gamma_default, |
45 | 59 | };
|
46 | 60 |
|
47 | 61 | static struct fb_deferred_io rpisense_fb_defio;
|
@@ -127,13 +141,54 @@ static struct fb_deferred_io rpisense_fb_defio = {
|
127 | 141 | .deferred_io = rpisense_fb_deferred_io,
|
128 | 142 | };
|
129 | 143 |
|
| 144 | +static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd, |
| 145 | + unsigned long arg) |
| 146 | +{ |
| 147 | + switch (cmd) { |
| 148 | + case SENSEFB_FBIOGET_GAMMA: |
| 149 | + if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma, |
| 150 | + sizeof(u8[32]))) |
| 151 | + return -EFAULT; |
| 152 | + return 0; |
| 153 | + case SENSEFB_FBIOSET_GAMMA: |
| 154 | + if (copy_from_user(gamma_user, (void __user *)arg, |
| 155 | + sizeof(u8[32]))) |
| 156 | + return -EFAULT; |
| 157 | + rpisense_fb_param.gamma = gamma_user; |
| 158 | + schedule_delayed_work(&info->deferred_work, |
| 159 | + rpisense_fb_defio.delay); |
| 160 | + return 0; |
| 161 | + case SENSEFB_FBIORESET_GAMMA: |
| 162 | + switch (arg) { |
| 163 | + case 0: |
| 164 | + rpisense_fb_param.gamma = gamma_default; |
| 165 | + break; |
| 166 | + case 1: |
| 167 | + rpisense_fb_param.gamma = gamma_low; |
| 168 | + break; |
| 169 | + case 2: |
| 170 | + rpisense_fb_param.gamma = gamma_user; |
| 171 | + break; |
| 172 | + default: |
| 173 | + return -EINVAL; |
| 174 | + } |
| 175 | + schedule_delayed_work(&info->deferred_work, |
| 176 | + rpisense_fb_defio.delay); |
| 177 | + break; |
| 178 | + default: |
| 179 | + return -EINVAL; |
| 180 | + } |
| 181 | + return 0; |
| 182 | +} |
| 183 | + |
130 | 184 | static struct fb_ops rpisense_fb_ops = {
|
131 | 185 | .owner = THIS_MODULE,
|
132 | 186 | .fb_read = fb_sys_read,
|
133 | 187 | .fb_write = rpisense_fb_write,
|
134 | 188 | .fb_fillrect = rpisense_fb_fillrect,
|
135 | 189 | .fb_copyarea = rpisense_fb_copyarea,
|
136 | 190 | .fb_imageblit = rpisense_fb_imageblit,
|
| 191 | + .fb_ioctl = rpisense_fb_ioctl, |
137 | 192 | };
|
138 | 193 |
|
139 | 194 | static int rpisense_fb_probe(struct platform_device *pdev)
|
@@ -171,6 +226,9 @@ static int rpisense_fb_probe(struct platform_device *pdev)
|
171 | 226 | info->screen_base = rpisense_fb_param.vmem;
|
172 | 227 | info->screen_size = rpisense_fb_param.vmemsize;
|
173 | 228 |
|
| 229 | + if (lowlight) |
| 230 | + rpisense_fb_param.gamma = gamma_low; |
| 231 | + |
174 | 232 | fb_deferred_io_init(info);
|
175 | 233 |
|
176 | 234 | ret = register_framebuffer(info);
|
|
0 commit comments