예제 #1
0
파일: mmp_ctrl.c 프로젝트: 19Dan01/linux
static void dmafetch_onoff(struct mmp_overlay *overlay, int on)
{
	u32 mask = overlay_is_vid(overlay) ? CFG_DMA_ENA_MASK :
		   CFG_GRA_ENA_MASK;
	u32 enable = overlay_is_vid(overlay) ? CFG_DMA_ENA(1) : CFG_GRA_ENA(1);
	u32 tmp;
	struct mmp_path *path = overlay->path;

	mutex_lock(&overlay->access_ok);
	tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id));
	tmp &= ~mask;
	tmp |= (on ? enable : 0);
	writel(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
	mutex_unlock(&overlay->access_ok);
}
예제 #2
0
static int dovefb_ovly_ioctl(struct fb_info *fi, unsigned int cmd,
		unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct dovefb_layer_info *dfli = fi->par;
	u32 x;
	int vmode = 0;
	int gfx_on = 1;
	int vid_on = 1;
	int interpolation = 0;

	switch (cmd) {
	case DOVEFB_IOCTL_WAIT_VSYNC:
		wait_for_vsync(dfli);
		break;
	case DOVEFB_IOCTL_GET_VIEWPORT_INFO:
		return copy_to_user(argp, &dfli->surface.viewPortInfo,
			sizeof(struct _sViewPortInfo)) ? -EFAULT : 0;
	case DOVEFB_IOCTL_SET_VIEWPORT_INFO:
		mutex_lock(&dfli->access_ok);
		if (copy_from_user(&gViewPortInfo, argp,
				sizeof(gViewPortInfo))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}

		if (check_surface(fi, -1, &gViewPortInfo, 0, 0))
			dovefb_ovly_set_par(fi);

		mutex_unlock(&dfli->access_ok);
		break;
	case DOVEFB_IOCTL_SET_VIDEO_MODE:
		/*
		 * Get data from user space.
		 */
		if (copy_from_user(&vmode, argp, sizeof(vmode)))
			return -EFAULT;

		if (check_surface(fi, vmode, 0, 0, 0))
			dovefb_ovly_set_par(fi);
		break;
	case DOVEFB_IOCTL_GET_VIDEO_MODE:
		return copy_to_user(argp, &dfli->surface.videoMode,
			sizeof(u32)) ? -EFAULT : 0;
	case DOVEFB_IOCTL_CREATE_VID_BUFFER:
	{
		struct _sOvlySurface OvlySurface;

		mutex_lock(&dfli->access_ok);
		if (copy_from_user(&OvlySurface, argp,
				sizeof(struct _sOvlySurface))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}

		/* Request a video buffer. */
		dovefb_ovly_create_surface(&OvlySurface);

		if (copy_to_user(argp, &OvlySurface,
				sizeof(struct _sOvlySurface))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}

		mutex_unlock(&dfli->access_ok);

		break;
	}
	case DOVEFB_IOCTL_FLIP_VID_BUFFER:
	{
		struct _sOvlySurface *surface = 0;
		u8 *start_addr, *input_data, *dst_addr;
		u32 length;
		surface = kmalloc(sizeof(struct _sOvlySurface),
				GFP_KERNEL);

		/* Get user-mode data. */
		if (copy_from_user(surface, argp,
		    sizeof(struct _sOvlySurface))) {
			kfree(surface);
			return -EFAULT;
		}
		mutex_lock(&dfli->access_ok);
		length = surface->videoBufferAddr.length;
		dst_addr = dfli->surface.videoBufferAddr.startAddr;
		start_addr = surface->videoBufferAddr.startAddr;
		input_data = surface->videoBufferAddr.inputData;

		/*
		 * Has DMA addr?
		 */
		if (start_addr &&
		    (!input_data)) {
			if (0 != addFreeBuf(freeBufList, (u8 *)surface)) {
				pr_debug("Error: addFreeBuf()\n");
				mutex_unlock(&dfli->access_ok);
				kfree(surface);
				return -EFAULT;
			} else {
				/* pr_debug("addFreeBuf(0x%08x) ok.\n",
					start_addr); */
			}
		} else {
			if (check_surface(fi, surface->videoMode,
					&surface->viewPortInfo,
					&surface->viewPortOffset,
					&surface->videoBufferAddr))
				dovefb_ovly_set_par(fi);

			/* copy buffer */
			if (input_data) {
				wait_for_vsync(dfli);
				/* if support hw DMA, replace this. */
				if (copy_from_user(dfli->fb_start,
						   input_data, length)) {
					mutex_unlock(&dfli->access_ok);
					kfree(surface);
					return -EFAULT;
				}
				mutex_unlock(&dfli->access_ok);
				kfree(surface);
				return 0;
			}

			kfree(surface);
#if 0
			/*
			 * Fix me: Currently not implemented yet.
			 * Application allocate a physical contiguous
			 * buffer and pass it into driver. Here is to
			 * update fb's info to new buffer and free
			 * old buffer.
			 */
			if (start_addr) {
				if (dfli->mem_status)
					free_pages(
					    (unsigned long)dfli->fb_start,
					    get_order(dfli->fb_size));
				else
					dma_free_writecombine(dfli->dev,
					    dfli->fb_size,
					    dfli->fb_start,
					    dfli->fb_start_dma);

				dfli->fb_start = __va(start_addr);
				dfli->fb_size = length;
				dfli->fb_start_dma =
				    (dma_addr_t)__pa(dfli->fb_start);
				dfli->mem_status = 1;
				fi->fix.smem_start = dfli->fb_start_dma;
				fi->fix.smem_len = dfli->fb_size;
				fi->screen_base = dfli->fb_start;
				fi->screen_size = dfli->fb_size;
			}
#endif
		}
		mutex_unlock(&dfli->access_ok);
		return 0;
	}
	case DOVEFB_IOCTL_GET_FREELIST:
	{
		mutex_lock(&dfli->access_ok);

		if (copy_to_user(argp, filterBufList,
				MAX_QUEUE_NUM*sizeof(u8 *))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}

		clearFreeBuf(filterBufList, RESET_BUF);

		mutex_unlock(&dfli->access_ok);
		return 0;
	}
	case DOVEFB_IOCTL_GET_BUFF_ADDR:
	{
		return copy_to_user(argp, &dfli->surface.videoBufferAddr,
			sizeof(struct _sVideoBufferAddr)) ? -EFAULT : 0;
	}
	case DOVEFB_IOCTL_SET_VID_OFFSET:
		mutex_lock(&dfli->access_ok);
		if (copy_from_user(&gViewPortOffset, argp,
				sizeof(gViewPortOffset))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}

		if (check_surface(fi, -1, 0, &gViewPortOffset, 0))
			dovefb_ovly_set_par(fi);
		mutex_unlock(&dfli->access_ok);
		break;
	case DOVEFB_IOCTL_GET_VID_OFFSET:
		return copy_to_user(argp, &dfli->surface.viewPortOffset,
			sizeof(struct _sViewPortOffset)) ? -EFAULT : 0;
	case DOVEFB_IOCTL_SET_MEMORY_TOGGLE:
		break;
	case DOVEFB_IOCTL_SET_COLORKEYnALPHA:
		if (copy_from_user(&dfli->ckey_alpha, argp,
		    sizeof(struct _sColorKeyNAlpha)))
			return -EFAULT;

		dovefb_ovly_set_colorkeyalpha(dfli);
		break;
	case DOVEFB_IOCTL_GET_COLORKEYnALPHA:
		if (copy_to_user(argp, &dfli->ckey_alpha,
		    sizeof(struct _sColorKeyNAlpha)))
			return -EFAULT;
		break;
	case DOVEFB_IOCTL_SWITCH_VID_OVLY:
		if (copy_from_user(&vid_on, argp, sizeof(int)))
			return -EFAULT;
		if (0 == vid_on) {
			x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) &
				~CFG_DMA_ENA_MASK;
			writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0);
		} else {
			x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) |
				CFG_DMA_ENA(0x1);
			writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0);
			/* Enable VID & VSync. */
			x = readl(dfli->reg_base + SPU_IRQ_ENA) |
				DOVEFB_VID_INT_MASK | DOVEFB_VSYNC_INT_MASK;
			writel(x, dfli->reg_base + SPU_IRQ_ENA);
		}
		break;
	case DOVEFB_IOCTL_SWITCH_GRA_OVLY:
		if (copy_from_user(&gfx_on, argp, sizeof(int)))
			return -EFAULT;
		if (0 == gfx_on) {
			x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) &
				~CFG_GRA_ENA_MASK;
			writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0);
		} else {
			x = readl(dfli->reg_base + LCD_SPU_DMA_CTRL0) |
				CFG_GRA_ENA(0x1);
			writel(x, dfli->reg_base + LCD_SPU_DMA_CTRL0);
		}
		break;
	case DOVEFB_IOCTL_GET_FBID:
		mutex_lock(&dfli->access_ok);
		if (copy_to_user(argp, &dfli->cur_fbid, sizeof(unsigned int))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}
		mutex_unlock(&dfli->access_ok);
		break;
	case DOVEFB_IOCTL_GET_SRC_MODE:
		mutex_lock(&dfli->access_ok);
		if (copy_to_user(argp, &dfli->src_mode, sizeof(int))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}
		mutex_unlock(&dfli->access_ok);
		break;
	case DOVEFB_IOCTL_SET_SRC_MODE:
		mutex_lock(&dfli->access_ok);
		if (copy_from_user(&dfli->src_mode, argp, sizeof(int))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}

		if (SHM_NORMAL == dfli->src_mode) {
			int i;

			/*
			 * Recycle all video buffer.
			 */
			/* 1. collect freelist buffer */
			for (i = (MAX_QUEUE_NUM-1); i >= 0; i--) {
				if (freeBufList[i])
					break;
			}
			collectFreeBuf(filterBufList, freeBufList, (i));

			/* 2. Recycle current frame to filter list. */
			for (i = 0; i < MAX_QUEUE_NUM; i++) {
				if (!filterBufList[i])
					filterBufList[i] = (u8 *)dfli->new_addr;
			}

			/* clear and reset related resource. */
			clearFreeBuf(freeBufList, RESET_BUF|FREE_ENTRY);
			dfli->new_addr = 0;
			dfli->cur_fbid = 0;
			memset(dfli->fb_start, 0, dfli->fb_size);
		}

		mutex_unlock(&dfli->access_ok);
		break;
	case DOVEFB_IOCTL_GET_FBPA:
		{
		struct shm_private_info info;
		int index;

		if (copy_from_user(&info, argp,
		    sizeof(struct shm_private_info)))
			return -EFAULT;

		/* which frame want to find. */
		index = info.fbid;

		/* calc physical address. */
		info.fb_pa = (unsigned long)(dfli->fb_start_dma+
				(index*info.width*info.height*MAX_YUV_PIXEL));
		if (copy_to_user(argp, &info, sizeof(struct shm_private_info)))
			return -EFAULT;

		break;
		}
	case DOVEFB_IOCTL_NEXT_FRAME_PRESENT:
		{
		unsigned int phy_addr[3];
		mutex_lock(&dfli->access_ok);
		if (copy_from_user(&phy_addr, argp, 3*sizeof(unsigned int))) {
			mutex_unlock(&dfli->access_ok);
			return -EFAULT;
		}
		mutex_unlock(&dfli->access_ok);
		dfli->vid_ovly_phys_addr_y = phy_addr[0];
		dfli->vid_ovly_phys_addr_u = phy_addr[1];
		dfli->vid_ovly_phys_addr_v = phy_addr[2];
		break;
		}
	case DOVEFB_IOCTL_SET_INTERPOLATION_MODE:
		/*
		 * Get data from user space.
		 */
		if (copy_from_user(&interpolation, argp, sizeof(interpolation)))
			return -EFAULT;
		if ((interpolation == 0) || (interpolation == 3))
			writel(CFG_VSC_LINEAR(interpolation) |
				(readl(dfli->reg_base +	SPU_IOPAD_CONTROL) &
				!CFG_VSC_LINEAR_MASK),
				dfli->reg_base + SPU_IOPAD_CONTROL);
		break;
	default:
		pr_debug("ioctl_ovly(0x%x) No match.\n", cmd);
		break;
	}

	return 0;
}
static int pxa168fb_ovly_ioctl(struct fb_info *fi, unsigned int cmd,
			unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct pxa168fb_info *fbi = (struct pxa168fb_info *)fi->par;
	struct pxa168fb_mach_info *mi = fbi->dev->platform_data;
	int vid_on = 1;
	int val = 0, mask = 0;
	unsigned char param;
	int blendval = 0;
	int res, tmp;
	int ret = 0;
	unsigned long flags;

#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
	debug_identify_called_ioctl(fi, cmd, arg);
#endif

	switch (cmd) {
	case FB_IOCTL_CLEAR_FRAMEBUFFER:
		if (!mi->mmap)
			return -EINVAL;
		pxa168fb_clear_framebuffer(fi);
		return 0;
		break;
	case FB_IOCTL_WAIT_VSYNC:
		param = (arg & 0x3);
		wait_for_vsync(fbi, param);
		break;
	case FB_IOCTL_GET_VIEWPORT_INFO:/*if rotate 90/270, w/h swap*/
		mutex_lock(&fbi->access_ok);
		if (fbi->surface.viewPortInfo.rotation == 90 ||
			fbi->surface.viewPortInfo.rotation == 270) {
			tmp = fbi->surface.viewPortInfo.srcWidth;
			fbi->surface.viewPortInfo.srcWidth =
			fbi->surface.viewPortInfo.srcHeight;
			fbi->surface.viewPortInfo.srcHeight = tmp;
			fbi->surface.viewPortInfo.rotation = 360 -
			fbi->surface.viewPortInfo.rotation;
		}
		res = copy_to_user(argp, &fbi->surface.viewPortInfo,
			sizeof(struct _sViewPortInfo)) ? -EFAULT : 0;
		if (fbi->surface.viewPortInfo.rotation == 90 ||
			fbi->surface.viewPortInfo.rotation == 270) {
			tmp = fbi->surface.viewPortInfo.srcWidth;
			fbi->surface.viewPortInfo.srcWidth =
			fbi->surface.viewPortInfo.srcHeight;
			fbi->surface.viewPortInfo.srcHeight = tmp;
			fbi->surface.viewPortInfo.rotation = 360 -
			fbi->surface.viewPortInfo.rotation;
		}
		mutex_unlock(&fbi->access_ok);
		return res;
	case FB_IOCTL_SET_VIEWPORT_INFO:/*if rotate 90/270, w/h swap*/
		mutex_lock(&fbi->access_ok);
		memset(&gOvlySurface, 0, sizeof(gOvlySurface));
		gOvlySurface.videoMode = -1;
		if (copy_from_user(&gOvlySurface.viewPortInfo, argp,
				sizeof(gOvlySurface.viewPortInfo))) {
			mutex_unlock(&fbi->access_ok);
			return -EFAULT;
		}
		if (unsupport_format(fbi, gOvlySurface.viewPortInfo, -1)) {
			mutex_unlock(&fbi->access_ok);
			return -EFAULT;
		}
		gOvlySurface.viewPortInfo.rotation =
		 (360 - gOvlySurface.viewPortInfo.rotation) % 360;
		if (gOvlySurface.viewPortInfo.rotation == 90 ||
			gOvlySurface.viewPortInfo.rotation == 270) {
			tmp = gOvlySurface.viewPortInfo.srcWidth;
			gOvlySurface.viewPortInfo.srcWidth =
			gOvlySurface.viewPortInfo.srcHeight;
			gOvlySurface.viewPortInfo.srcHeight = tmp;
		}

		ret = check_surface(fi, &gOvlySurface);
		if (ret > 0) {
			pxa168fb_set_par(fi);
			ret = 0;
		} else if (ret < 0) {
			pr_err("fbi %d (line %d): vid %d, check surface"
				"return error\n", fbi->id, __LINE__, fbi->vid);
			ret = -EFAULT;
		}
		mutex_unlock(&fbi->access_ok);
		return ret;
		break;
	case FB_IOCTL_SET_VIDEO_MODE:
		/*
		 * Get data from user space.
		 */
		memset(&gOvlySurface, 0, sizeof(gOvlySurface));
		if (copy_from_user(&gOvlySurface.videoMode, argp,
				 sizeof(gOvlySurface.videoMode)))
			return -EFAULT;

		if (unsupport_format(fbi, gOvlySurface.viewPortInfo,
			 gOvlySurface.videoMode))
			return -EFAULT;
		ret = check_surface(fi, &gOvlySurface);
		if (ret > 0) {
			pxa168fb_set_par(fi);
			ret = 0;
		} else if (ret < 0) {
			pr_err("fbi %d (line %d): vid %d, check surface"
				"return error\n", fbi->id, __LINE__, fbi->vid);
			ret = -EFAULT;
		}
		return ret;
		break;
	case FB_IOCTL_GET_VIDEO_MODE:
		return copy_to_user(argp, &fbi->surface.videoMode,
			sizeof(u32)) ? -EFAULT : 0;
	case FB_IOCTL_FLIP_VID_BUFFER:
		return flip_buffer(fi, arg);
	case FB_IOCTL_GET_FREELIST:
		return get_freelist(fi, arg);
	case FB_IOCTL_FLIP_VSYNC:
		return flip_buffer_vsync(fi, arg);
	case FB_IOCTL_GET_BUFF_ADDR:
	{
		return copy_to_user(argp, &fbi->surface.videoBufferAddr,
			sizeof(struct _sVideoBufferAddr)) ? -EFAULT : 0;
	}
	case FB_IOCTL_SET_VID_OFFSET:
		mutex_lock(&fbi->access_ok);
		memset(&gOvlySurface, 0, sizeof(gOvlySurface));
		gOvlySurface.videoMode = -1;
		if (copy_from_user(&gOvlySurface.viewPortOffset, argp,
				sizeof(gOvlySurface.viewPortOffset))) {
			mutex_unlock(&fbi->access_ok);
			return -EFAULT;
		}

		ret = check_surface(fi, &gOvlySurface);
		if (ret > 0) {
			pxa168fb_set_par(fi);
			ret = 0;
		} else if (ret < 0) {
			pr_err("fbi %d (line %d): vid %d, check surface"
				"return error\n", fbi->id, __LINE__, fbi->vid);
			ret = -EFAULT;
		}
		mutex_unlock(&fbi->access_ok);
		return ret;
		break;
	case FB_IOCTL_GET_VID_OFFSET:
		return copy_to_user(argp, &fbi->surface.viewPortOffset,
			sizeof(struct _sViewPortOffset)) ? -EFAULT : 0;

	case FB_IOCTL_SET_SURFACE:
	{
		mutex_lock(&fbi->access_ok);
		/* Get user-mode data. */
		if (copy_from_user(&fbi->surface_bak, argp,
					sizeof(struct _sOvlySurface))) {
			mutex_unlock(&fbi->access_ok);
			return -EFAULT;
		}
		fbi->surface_set = 1;

		mutex_unlock(&fbi->access_ok);
		return 0;
	}
	case FB_IOCTL_GET_SURFACE:
	{
		mutex_lock(&fbi->access_ok);
		if (fbi->surface_set) {
			ret = copy_to_user(argp, &fbi->surface_bak,
				sizeof(struct _sOvlySurface));
		} else {
		    ret = copy_to_user(argp, &fbi->surface,
				sizeof(struct _sOvlySurface));
		}

		ret = (ret ? -EFAULT : 0);
		mutex_unlock(&fbi->access_ok);
		return ret;
	}

	case FB_IOCTL_SET_COLORKEYnALPHA:
		if (copy_from_user(&fbi->ckey_alpha, argp,
		    sizeof(struct _sColorKeyNAlpha)))
			return -EFAULT;

		pxa168fb_ovly_set_colorkeyalpha(fbi);
		break;

	case FB_IOCTL_GET_COLORKEYnALPHA:
		if (copy_to_user(argp, &fbi->ckey_alpha,
		    sizeof(struct _sColorKeyNAlpha)))
			return -EFAULT;
		break;
	case FB_IOCTL_SWITCH_VID_OVLY:
		if (copy_from_user(&vid_on, argp, sizeof(int)))
			return -EFAULT;
		spin_lock_irqsave(&fbi->var_lock, flags);
		mask = CFG_DMA_ENA_MASK;

		fbi->dma_on = vid_on ? 1 : 0;
		val = CFG_DMA_ENA(check_modex_active(fbi));
		if (!val && gfx_info.fbi[0]->active) {
			pxa688_vdma_release(fbi->id, fbi->vid);
			/* switch off, disable DMA */
			dma_ctrl_set(fbi->id, 0, mask, val);
		} else if (list_empty(&fbi->buf_waitlist.dma_queue) &&
			!fbi->buf_current)
			/* switch on, but no buf flipped, return error */
			; /* ret = -EAGAIN; */

		printk(KERN_DEBUG "SWITCH_VID_OVLY fbi %d dma_on %d,"
			" val %d, waitlist empty %d buf_current %p, ret %d\n",
			fbi->id, fbi->dma_on, val,
			list_empty(&fbi->buf_waitlist.dma_queue),
			fbi->buf_current, ret);

		pxa688fb_vsmooth_set(fbi->id, 1, vid_vsmooth & vid_on);

		spin_unlock_irqrestore(&fbi->var_lock, flags);
		return ret;
		break;

	case FB_IOCTL_SWAP_VIDEO_RED_BLUE:
		param = (arg & 0x1);
		dma_ctrl_set(fbi->id, 0, CFG_DMA_SWAPRB_MASK,
				 CFG_DMA_SWAPRB(param));
		return 0;
		break;

	case FB_IOCTL_SWAP_VIDEO_U_V:
		param = (arg & 0x1);
		dma_ctrl_set(fbi->id, 0, CFG_DMA_SWAPUV_MASK,
				 CFG_DMA_SWAPUV(param));
		return 0;
		break;

	case FB_IOCTL_SWAP_VIDEO_Y_UV:
		param = (arg & 0x1);
		dma_ctrl_set(fbi->id, 0, CFG_DMA_SWAPYU_MASK,
				 CFG_DMA_SWAPYU(param));
		return 0;
		break;

	case FB_IOCTL_PUT_VIDEO_ALPHABLEND:
		/*
		 *  This puts the blending control to the Video layer.
		 */
		mask = CFG_ALPHA_MODE_MASK | CFG_ALPHA_MASK;
		val = CFG_ALPHA_MODE(0) | CFG_ALPHA(0xff);
		dma_ctrl_set(fbi->id, 1, mask, val);
		return 0;
		break;

	case FB_IOCTL_PUT_GLOBAL_ALPHABLEND:
		/*
		 *  The userspace application can specify a byte value for the
		 *  amount of global blend between the video layer and thei
		 *  graphic layer.
		 *
		 *  The alpha blending is per the formula below:
		 *  P = (V[P] * blendval/255) + (G[P] * (1 - blendval/255))
		 *  where: P = Pixel value, V = Video Layer,
		 *  and G = Graphic Layer
		 */
		blendval = (arg & 0xff);
		mask = CFG_ALPHA_MODE_MASK | CFG_ALPHA_MASK;
		val = CFG_ALPHA_MODE(2) | CFG_ALPHA(blendval);
		dma_ctrl_set(fbi->id, 1, mask, val);
		return 0;
		break;

	case FB_IOCTL_PUT_GRAPHIC_ALPHABLEND:
		/*
		 *  This puts the blending back to the default mode of allowing
		 *  the graphic layer to do pixel level blending.
		 */
		mask = CFG_ALPHA_MODE_MASK | CFG_ALPHA_MASK;
		val = CFG_ALPHA_MODE(1) | CFG_ALPHA(0x0);
		dma_ctrl_set(fbi->id, 1, mask, val);
		return 0;
		break;

	default:
		break;
	}

	return 0;
}