drivers/video/fbdev/clps711x-fb.c

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/clps711x-fb.c

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/clps711x-fb.c
Extension
.c
Size
9225 bytes
Lines
375
Domain
Driver Families
Bucket
drivers/video
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct clps711x_fb_info {
	struct clk		*clk;
	void __iomem		*base;
	struct regmap		*syscon;
	resource_size_t		buffsize;
	struct fb_videomode	mode;
	struct regulator	*lcd_pwr;
	u32			ac_prescale;
	bool			cmap_invert;
};

static int clps711x_fb_setcolreg(u_int regno, u_int red, u_int green,
				 u_int blue, u_int transp, struct fb_info *info)
{
	struct clps711x_fb_info *cfb = info->par;
	u32 level, mask, shift;

	if (regno >= BIT(info->var.bits_per_pixel))
		return -EINVAL;

	shift = 4 * (regno & 7);
	mask  = 0xf << shift;
	/* gray = 0.30*R + 0.58*G + 0.11*B */
	level = (((red * 77 + green * 151 + blue * 28) >> 20) << shift) & mask;
	if (cfb->cmap_invert)
		level = 0xf - level;

	regno = (regno < 8) ? CLPS711X_PALLSW : CLPS711X_PALMSW;

	writel((readl(cfb->base + regno) & ~mask) | level, cfb->base + regno);

	return 0;
}

static int clps711x_fb_check_var(struct fb_var_screeninfo *var,
				 struct fb_info *info)
{
	u32 val;

	if (var->bits_per_pixel < 1 ||
	    var->bits_per_pixel > CLPS711X_FB_BPP_MAX)
		return -EINVAL;

	if (!var->pixclock)
		return -EINVAL;

	val = DIV_ROUND_UP(var->xres, 16) - 1;
	if (val < 0x01 || val > 0x3f)
		return -EINVAL;

	val = DIV_ROUND_UP(var->yres * var->xres * var->bits_per_pixel, 128);
	val--;
	if (val < 0x001 || val > 0x1fff)
		return -EINVAL;

	var->transp.msb_right	= 0;
	var->transp.offset	= 0;
	var->transp.length	= 0;
	var->red.msb_right	= 0;
	var->red.offset		= 0;
	var->red.length		= var->bits_per_pixel;
	var->green		= var->red;
	var->blue		= var->red;
	var->grayscale		= var->bits_per_pixel > 1;

	return 0;
}

static int clps711x_fb_set_par(struct fb_info *info)
{
	struct clps711x_fb_info *cfb = info->par;
	resource_size_t size;
	u32 lcdcon, pps;

	size = (info->var.xres * info->var.yres * info->var.bits_per_pixel) / 8;
	if (size > cfb->buffsize)
		return -EINVAL;

	switch (info->var.bits_per_pixel) {
	case 1:
		info->fix.visual = FB_VISUAL_MONO01;
		break;
	case 2:
	case 4:
		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
		break;
	default:
		return -EINVAL;
	}

Annotation

Implementation Notes