metronomefb: Add rotation support and some minor cleanups
SVN-Revision: 20128
This commit is contained in:
parent
c239c05829
commit
bf31e79489
2 changed files with 217 additions and 99 deletions
|
@ -19,8 +19,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
@ -44,10 +42,6 @@
|
||||||
|
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
/* Display specific information */
|
|
||||||
#define DPY_W 832
|
|
||||||
#define DPY_H 622
|
|
||||||
|
|
||||||
#define WF_MODE_INIT 0 /* Initialization */
|
#define WF_MODE_INIT 0 /* Initialization */
|
||||||
#define WF_MODE_MU 1 /* Monochrome update */
|
#define WF_MODE_MU 1 /* Monochrome update */
|
||||||
#define WF_MODE_GU 2 /* Grayscale update */
|
#define WF_MODE_GU 2 /* Grayscale update */
|
||||||
|
@ -63,7 +57,7 @@ struct epd_frame {
|
||||||
int wfm_size;
|
int wfm_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct epd_frame epd_frame_table[] = {
|
static const struct epd_frame epd_frame_table[] = {
|
||||||
{
|
{
|
||||||
.fw = 832,
|
.fw = 832,
|
||||||
.fh = 622,
|
.fh = 622,
|
||||||
|
@ -130,22 +124,17 @@ static struct epd_frame epd_frame_table[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fb_fix_screeninfo metronomefb_fix __devinitdata = {
|
static const struct fb_fix_screeninfo metronomefb_fix __devinitconst = {
|
||||||
.id = "metronomefb",
|
.id = "metronomefb",
|
||||||
.type = FB_TYPE_PACKED_PIXELS,
|
.type = FB_TYPE_PACKED_PIXELS,
|
||||||
.visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
|
.visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
|
||||||
.xpanstep = 0,
|
.xpanstep = 0,
|
||||||
.ypanstep = 0,
|
.ypanstep = 0,
|
||||||
.ywrapstep = 0,
|
.ywrapstep = 0,
|
||||||
.line_length = DPY_W,
|
|
||||||
.accel = FB_ACCEL_NONE,
|
.accel = FB_ACCEL_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fb_var_screeninfo metronomefb_var __devinitdata = {
|
static const struct fb_var_screeninfo metronomefb_var __devinitconst = {
|
||||||
.xres = DPY_W,
|
|
||||||
.yres = DPY_H,
|
|
||||||
.xres_virtual = DPY_W,
|
|
||||||
.yres_virtual = DPY_H,
|
|
||||||
.bits_per_pixel = 8,
|
.bits_per_pixel = 8,
|
||||||
.grayscale = 1,
|
.grayscale = 1,
|
||||||
.nonstd = 1,
|
.nonstd = 1,
|
||||||
|
@ -365,7 +354,6 @@ static int metronome_display_cmd(struct metronomefb_par *par)
|
||||||
int i;
|
int i;
|
||||||
u16 cs;
|
u16 cs;
|
||||||
u16 opcode;
|
u16 opcode;
|
||||||
static u8 borderval;
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = wait_for_rdy(par);
|
res = wait_for_rdy(par);
|
||||||
|
@ -442,8 +430,8 @@ static int __devinit metronome_config_cmd(struct metronomefb_par *par)
|
||||||
will try parse the command before we've set it all up */
|
will try parse the command before we've set it all up */
|
||||||
|
|
||||||
dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__);
|
dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__);
|
||||||
memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config,
|
memcpy(par->metromem_cmd->args, par->epd_frame->config,
|
||||||
sizeof(epd_frame_table[par->dt].config));
|
sizeof(par->epd_frame->config));
|
||||||
/* the rest are 0 */
|
/* the rest are 0 */
|
||||||
memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2);
|
memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2);
|
||||||
|
|
||||||
|
@ -520,35 +508,102 @@ static int __devinit metronome_init_regs(struct metronomefb_par *par)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void metronomefb_dpy_update(struct metronomefb_par *par, int clear_all)
|
static uint16_t metronomefb_update_img_buffer_rotated(struct metronomefb_par *par)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int i;
|
int xstep, ystep;
|
||||||
u16 cksum = 0;
|
int i, j;
|
||||||
u32 *buf = (u32 __force *)par->info->screen_base;
|
uint16_t cksum = 0;
|
||||||
u32 *img = (u32 *)(par->metromem_img);
|
uint8_t *buf = par->info->screen_base;
|
||||||
u32 diff;
|
uint32_t *img = (uint32_t *)(par->metromem_img);
|
||||||
u32 tmp;
|
int fw = par->epd_frame->fw;
|
||||||
unsigned int fbsize = par->info->fix.smem_len;
|
int fh = par->epd_frame->fh;
|
||||||
int fx = par->info->fix.line_length;
|
int fw_buf = fw / 4;
|
||||||
int fy = fbsize / fx;
|
uint32_t *fxbuckets = par->fxbuckets;
|
||||||
int fx_buf = fx / sizeof(*buf);
|
uint32_t *fybuckets = par->fybuckets;
|
||||||
int m;
|
uint32_t diff;
|
||||||
static int is_first_update = 1;
|
uint32_t tmp;
|
||||||
static int partial_updates_count = 0;
|
|
||||||
u32 *fxbuckets = par->fxbuckets;
|
|
||||||
u32 *fybuckets = par->fybuckets;
|
|
||||||
|
|
||||||
wait_for_rdy(par);
|
switch (par->info->var.rotate) {
|
||||||
|
case FB_ROTATE_CW:
|
||||||
|
xstep = -fh;
|
||||||
|
ystep = fw * fh + 1;
|
||||||
|
j = (fw - 1) * fh;
|
||||||
|
break;
|
||||||
|
case FB_ROTATE_UD:
|
||||||
|
xstep = -1;
|
||||||
|
ystep = 0;
|
||||||
|
j = fw * fh - 1;
|
||||||
|
break;
|
||||||
|
case FB_ROTATE_CCW:
|
||||||
|
xstep = fh;
|
||||||
|
ystep = -fw * fh - 1;
|
||||||
|
j = fh - 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
memset(fxbuckets, 0, fx_buf * sizeof(*fxbuckets));
|
memset(fxbuckets, 0, fw_buf * sizeof(*fxbuckets));
|
||||||
memset(fybuckets, 0, fy * sizeof(*fybuckets));
|
memset(fybuckets, 0, fh * sizeof(*fybuckets));
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (y = 0; y < fy; y++) {
|
for (y = 0; y < fh; y++) {
|
||||||
for(x = 0; x < fx_buf; x++, i++) {
|
for(x = 0; x < fw_buf; x++, i++) {
|
||||||
tmp = (buf[i] << 5) & 0xE0E0E0E0;
|
if (j < 0 || j >= fw * fh) {
|
||||||
img[i] &= 0xF0F0F0F0;
|
printk("moo: %d %d %d %d %d\n", j, x, y, fw_buf, fh);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tmp = (buf[j] << 5);
|
||||||
|
j += xstep;
|
||||||
|
tmp |= (buf[j] << 13);
|
||||||
|
j += xstep;
|
||||||
|
tmp |= (buf[j] << 21);
|
||||||
|
j += xstep;
|
||||||
|
tmp |= (buf[j] << 29);
|
||||||
|
j += xstep;
|
||||||
|
tmp &= 0xe0e0e0e0;
|
||||||
|
|
||||||
|
img[i] &= 0xf0f0f0f0;
|
||||||
|
diff = img[i] ^ tmp;
|
||||||
|
|
||||||
|
fxbuckets[x] |= diff;
|
||||||
|
fybuckets[y] |= diff;
|
||||||
|
|
||||||
|
img[i] = (img[i] >> 4) | tmp;
|
||||||
|
cksum += img[i] & 0x0000ffff;
|
||||||
|
cksum += (img[i] >> 16);
|
||||||
|
|
||||||
|
}
|
||||||
|
j += ystep;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t metronomefb_update_img_buffer_normal(struct metronomefb_par *par)
|
||||||
|
{
|
||||||
|
int x, y, i;
|
||||||
|
uint16_t cksum = 0;
|
||||||
|
uint32_t *buf = (uint32_t __force *)par->info->screen_base;
|
||||||
|
uint32_t *img = (uint32_t *)(par->metromem_img);
|
||||||
|
uint32_t diff;
|
||||||
|
uint32_t tmp;
|
||||||
|
int fw = par->epd_frame->fw;
|
||||||
|
int fh = par->epd_frame->fh;
|
||||||
|
int fw_buf = fw / sizeof(*buf);
|
||||||
|
uint32_t *fxbuckets = par->fxbuckets;
|
||||||
|
uint32_t *fybuckets = par->fybuckets;
|
||||||
|
|
||||||
|
memset(fxbuckets, 0, fw_buf * sizeof(*fxbuckets));
|
||||||
|
memset(fybuckets, 0, fh * sizeof(*fybuckets));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (y = 0; y < fh; y++) {
|
||||||
|
for(x = 0; x < fw_buf; x++, i++) {
|
||||||
|
tmp = (buf[i] << 5) & 0xe0e0e0e0;
|
||||||
|
img[i] &= 0xf0f0f0f0;
|
||||||
diff = img[i] ^ tmp;
|
diff = img[i] ^ tmp;
|
||||||
|
|
||||||
fxbuckets[x] |= diff;
|
fxbuckets[x] |= diff;
|
||||||
|
@ -560,73 +615,92 @@ static void metronomefb_dpy_update(struct metronomefb_par *par, int clear_all)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*((u16 *)(par->metromem_img) + fbsize/2) = cksum;
|
return cksum;
|
||||||
|
}
|
||||||
|
|
||||||
if (clear_all || is_first_update ||
|
static unsigned int metronomefb_get_change_count(struct metronomefb_par *par)
|
||||||
(partial_updates_count == par->partial_autorefresh_interval)) {
|
{
|
||||||
|
int min_x;
|
||||||
|
int max_x;
|
||||||
|
int min_y;
|
||||||
|
int max_y;
|
||||||
|
int fw = par->epd_frame->fw / 4;
|
||||||
|
int fh = par->epd_frame->fh;
|
||||||
|
unsigned int change_count;
|
||||||
|
uint32_t *fxbuckets = par->fxbuckets;
|
||||||
|
uint32_t *fybuckets = par->fybuckets;
|
||||||
|
|
||||||
|
for (min_x = 0; min_x < fw; ++min_x) {
|
||||||
|
if(fxbuckets[min_x])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (max_x = fw - 1; max_x >= 0; --max_x) {
|
||||||
|
if(fxbuckets[max_x])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (min_y = 0; min_y < fh; min_y++) {
|
||||||
|
if(fybuckets[min_y])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (max_y = fh - 1; max_y >= 0; --max_y) {
|
||||||
|
if(fybuckets[max_y])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((min_x > max_x) || (min_y > max_y))
|
||||||
|
change_count = 0;
|
||||||
|
else
|
||||||
|
change_count = (max_x - min_x + 1) * (max_y - min_y + 1) * 4;
|
||||||
|
|
||||||
|
dev_dbg(&par->pdev->dev, "min_x = %d, max_x = %d, min_y = %d, max_y = %d\n",
|
||||||
|
min_x, max_x, min_y, max_y);
|
||||||
|
|
||||||
|
return change_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void metronomefb_dpy_update(struct metronomefb_par *par, int clear_all)
|
||||||
|
{
|
||||||
|
unsigned int fbsize = par->info->fix.smem_len;
|
||||||
|
uint16_t cksum;
|
||||||
|
int m;
|
||||||
|
|
||||||
|
wait_for_rdy(par);
|
||||||
|
|
||||||
|
if (par->info->var.rotate == 0)
|
||||||
|
cksum = metronomefb_update_img_buffer_normal(par);
|
||||||
|
else
|
||||||
|
cksum = metronomefb_update_img_buffer_rotated(par);
|
||||||
|
|
||||||
|
*par->metromem_img_csum = __cpu_to_le16(cksum);
|
||||||
|
|
||||||
|
if (clear_all || par->is_first_update ||
|
||||||
|
(par->partial_updates_count == par->partial_autorefresh_interval)) {
|
||||||
m = WF_MODE_GC;
|
m = WF_MODE_GC;
|
||||||
partial_updates_count = 0;
|
par->partial_updates_count = 0;
|
||||||
} else {
|
} else {
|
||||||
int min_x = fx_buf;
|
int change_count = metronomefb_get_change_count(par);
|
||||||
int max_x = 0;
|
|
||||||
int min_y = fy;
|
|
||||||
int max_y = 0;
|
|
||||||
int change_count;
|
|
||||||
|
|
||||||
for (x = 0; x < fx_buf; x++)
|
|
||||||
if(fxbuckets[x]) {
|
|
||||||
min_x = x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = fx_buf - 1; x >= 0; x--)
|
|
||||||
if(fxbuckets[x]) {
|
|
||||||
max_x = x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0; y < fy; y++)
|
|
||||||
if(fybuckets[y]) {
|
|
||||||
min_y = y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = fy - 1; y >= 0; y--)
|
|
||||||
if(fybuckets[y]) {
|
|
||||||
max_y = y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((min_x > max_x) || (min_y > max_y))
|
|
||||||
change_count = 0;
|
|
||||||
else
|
|
||||||
change_count = (max_x - min_x + 1) * (max_y - min_y + 1) * sizeof(*buf);
|
|
||||||
|
|
||||||
if (change_count < fbsize / 100 * par->manual_refresh_threshold)
|
if (change_count < fbsize / 100 * par->manual_refresh_threshold)
|
||||||
m = WF_MODE_GU;
|
m = WF_MODE_GU;
|
||||||
else
|
else
|
||||||
m = WF_MODE_GC;
|
m = WF_MODE_GC;
|
||||||
|
|
||||||
dev_dbg(&par->pdev->dev, "min_x = %d, max_x = %d, min_y = %d, max_y = %d\n",
|
|
||||||
min_x, max_x, min_y, max_y);
|
|
||||||
dev_dbg(&par->pdev->dev, "change_count = %u, treshold = %u%% (%u pixels)\n",
|
dev_dbg(&par->pdev->dev, "change_count = %u, treshold = %u%% (%u pixels)\n",
|
||||||
change_count, par->manual_refresh_threshold,
|
change_count, par->manual_refresh_threshold,
|
||||||
fbsize / 100 * par->manual_refresh_threshold);
|
fbsize / 100 * par->manual_refresh_threshold);
|
||||||
|
++par->partial_updates_count;
|
||||||
partial_updates_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m != par->current_wf_mode) {
|
if (m != par->current_wf_mode)
|
||||||
load_waveform((u8 *) par->firmware->data, par->firmware->size,
|
load_waveform((u8 *) par->firmware->data, par->firmware->size,
|
||||||
m, par->current_wf_temp, par);
|
m, par->current_wf_temp, par);
|
||||||
}
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
if (likely(!check_err(par))) {
|
|
||||||
metronome_display_cmd(par);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
again:
|
||||||
|
metronome_display_cmd(par);
|
||||||
|
wait_for_rdy(par);
|
||||||
|
if (unlikely(check_err(par))) {
|
||||||
par->board->set_stdby(par, 0);
|
par->board->set_stdby(par, 0);
|
||||||
printk("Resetting Metronome\n");
|
printk("Resetting Metronome\n");
|
||||||
par->board->set_rst(par, 0);
|
par->board->set_rst(par, 0);
|
||||||
|
@ -637,12 +711,15 @@ static void metronomefb_dpy_update(struct metronomefb_par *par, int clear_all)
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
load_waveform((u8 *) par->firmware->data, par->firmware->size,
|
load_waveform((u8 *) par->firmware->data, par->firmware->size,
|
||||||
WF_MODE_GC, par->current_wf_temp, par);
|
WF_MODE_GC, par->current_wf_temp, par);
|
||||||
|
|
||||||
if (par->board->power_ctl)
|
if (par->board->power_ctl)
|
||||||
par->board->power_ctl(par, METRONOME_POWER_ON);
|
par->board->power_ctl(par, METRONOME_POWER_ON);
|
||||||
metronome_bootup(par);
|
metronome_bootup(par);
|
||||||
|
|
||||||
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_first_update = 0;
|
par->is_first_update = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is called back from the deferred io workqueue */
|
/* this is called back from the deferred io workqueue */
|
||||||
|
@ -742,12 +819,46 @@ static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf,
|
||||||
return (err) ? err : count;
|
return (err) ? err : count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int metronome_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||||
|
{
|
||||||
|
struct metronomefb_par *par = info->par;
|
||||||
|
|
||||||
|
if (par->epd_frame->fw == var->xres && par->epd_frame->fh == var->yres)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int metronomefb_set_par(struct fb_info *info)
|
||||||
|
{
|
||||||
|
struct metronomefb_par *par = info->par;
|
||||||
|
|
||||||
|
switch (info->var.rotate) {
|
||||||
|
case FB_ROTATE_CW:
|
||||||
|
case FB_ROTATE_CCW:
|
||||||
|
info->fix.line_length = info->var.yres;
|
||||||
|
break;
|
||||||
|
case FB_ROTATE_UD:
|
||||||
|
default:
|
||||||
|
info->fix.line_length = info->var.xres;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&par->lock);
|
||||||
|
metronomefb_dpy_update(info->par, 1);
|
||||||
|
mutex_unlock(&par->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct fb_ops metronomefb_ops = {
|
static struct fb_ops metronomefb_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.fb_write = metronomefb_write,
|
.fb_write = metronomefb_write,
|
||||||
.fb_fillrect = metronomefb_fillrect,
|
.fb_fillrect = metronomefb_fillrect,
|
||||||
.fb_copyarea = metronomefb_copyarea,
|
.fb_copyarea = metronomefb_copyarea,
|
||||||
.fb_imageblit = metronomefb_imageblit,
|
.fb_imageblit = metronomefb_imageblit,
|
||||||
|
.fb_check_var = metronome_check_var,
|
||||||
|
.fb_set_par = metronomefb_set_par,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct fb_deferred_io metronomefb_defio = {
|
static struct fb_deferred_io metronomefb_defio = {
|
||||||
|
@ -979,15 +1090,13 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
||||||
info->var.yres = fh;
|
info->var.yres = fh;
|
||||||
info->var.xres_virtual = fw;
|
info->var.xres_virtual = fw;
|
||||||
info->var.yres_virtual = fh;
|
info->var.yres_virtual = fh;
|
||||||
|
|
||||||
info->fix = metronomefb_fix;
|
info->fix = metronomefb_fix;
|
||||||
info->fix.smem_len = fw * fh; /* Real size of image area */
|
|
||||||
info->fix.line_length = fw;
|
info->fix.line_length = fw;
|
||||||
|
info->fix.smem_len = fw * fh; /* Real size of image area */
|
||||||
par = info->par;
|
par = info->par;
|
||||||
par->info = info;
|
par->info = info;
|
||||||
par->board = board;
|
par->board = board;
|
||||||
par->dt = epd_dt_index;
|
par->epd_frame = &epd_frame_table[epd_dt_index];
|
||||||
par->pdev = dev;
|
par->pdev = dev;
|
||||||
|
|
||||||
par->fxbuckets = kmalloc((fw / 4 + 1) * sizeof(*par->fxbuckets), GFP_KERNEL);
|
par->fxbuckets = kmalloc((fw / 4 + 1) * sizeof(*par->fxbuckets), GFP_KERNEL);
|
||||||
|
@ -1001,6 +1110,8 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
||||||
init_waitqueue_head(&par->waitq);
|
init_waitqueue_head(&par->waitq);
|
||||||
par->manual_refresh_threshold = 60;
|
par->manual_refresh_threshold = 60;
|
||||||
par->partial_autorefresh_interval = 256;
|
par->partial_autorefresh_interval = 256;
|
||||||
|
par->partial_updates_count = 0;
|
||||||
|
par->is_first_update = 1;
|
||||||
mutex_init(&par->lock);
|
mutex_init(&par->lock);
|
||||||
|
|
||||||
/* this table caches per page csum values. */
|
/* this table caches per page csum values. */
|
||||||
|
@ -1025,7 +1136,7 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
||||||
goto err_csum_table;
|
goto err_csum_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->fix.smem_start = 0;
|
info->fix.smem_start = par->metromem_dma;
|
||||||
|
|
||||||
/* load the waveform in. assume mode 3, temp 31 for now
|
/* load the waveform in. assume mode 3, temp 31 for now
|
||||||
a) request the waveform file from userspace
|
a) request the waveform file from userspace
|
||||||
|
@ -1173,6 +1284,7 @@ static int metronomefb_suspend(struct platform_device *pdev, pm_message_t messag
|
||||||
if (par->board->power_ctl)
|
if (par->board->power_ctl)
|
||||||
par->board->power_ctl(par, METRONOME_POWER_OFF);
|
par->board->power_ctl(par, METRONOME_POWER_OFF);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,9 @@ struct metromem_cmd {
|
||||||
u16 opcode;
|
u16 opcode;
|
||||||
u16 args[((64-2)/2)];
|
u16 args[((64-2)/2)];
|
||||||
u16 csum;
|
u16 csum;
|
||||||
} __attribute__(packed);
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct epd_frame;
|
||||||
|
|
||||||
/* struct used by metronome. board specific stuff comes from *board */
|
/* struct used by metronome. board specific stuff comes from *board */
|
||||||
struct metronomefb_par {
|
struct metronomefb_par {
|
||||||
|
@ -38,9 +40,13 @@ struct metronomefb_par {
|
||||||
int current_wf_temp;
|
int current_wf_temp;
|
||||||
unsigned int manual_refresh_threshold;
|
unsigned int manual_refresh_threshold;
|
||||||
unsigned int partial_autorefresh_interval;
|
unsigned int partial_autorefresh_interval;
|
||||||
int dt;
|
const struct epd_frame *epd_frame;
|
||||||
u32 *fxbuckets;
|
u32 *fxbuckets;
|
||||||
u32 *fybuckets;
|
u32 *fybuckets;
|
||||||
|
|
||||||
|
unsigned int partial_updates_count;
|
||||||
|
unsigned is_first_update:1;
|
||||||
|
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue