drivers/media/platform/ti/omap3isp/isph3a_aewb.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/ti/omap3isp/isph3a_aewb.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/ti/omap3isp/isph3a_aewb.c
Extension
.c
Size
10510 bytes
Lines
351
Domain
Driver Families
Bucket
drivers/media
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * isph3a.c
 *
 * TI OMAP3 ISP - H3A module
 *
 * Copyright (C) 2010 Nokia Corporation
 * Copyright (C) 2009 Texas Instruments, Inc.
 *
 * Contacts: David Cohen <dacohen@gmail.com>
 *	     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 *	     Sakari Ailus <sakari.ailus@iki.fi>
 */

#include <linux/slab.h>
#include <linux/uaccess.h>

#include "isp.h"
#include "isph3a.h"
#include "ispstat.h"

/*
 * h3a_aewb_update_regs - Helper function to update h3a registers.
 */
static void h3a_aewb_setup_regs(struct ispstat *aewb, void *priv)
{
	struct omap3isp_h3a_aewb_config *conf = priv;
	u32 pcr;
	u32 win1;
	u32 start;
	u32 blk;
	u32 subwin;

	if (aewb->state == ISPSTAT_DISABLED)
		return;

	isp_reg_writel(aewb->isp, aewb->active_buf->dma_addr,
		       OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST);

	if (!aewb->update)
		return;

	/* Converting config metadata into reg values */
	pcr = conf->saturation_limit << ISPH3A_PCR_AEW_AVE2LMT_SHIFT;
	pcr |= !!conf->alaw_enable << ISPH3A_PCR_AEW_ALAW_EN_SHIFT;

	win1 = ((conf->win_height >> 1) - 1) << ISPH3A_AEWWIN1_WINH_SHIFT;
	win1 |= ((conf->win_width >> 1) - 1) << ISPH3A_AEWWIN1_WINW_SHIFT;
	win1 |= (conf->ver_win_count - 1) << ISPH3A_AEWWIN1_WINVC_SHIFT;
	win1 |= (conf->hor_win_count - 1) << ISPH3A_AEWWIN1_WINHC_SHIFT;

	start = conf->hor_win_start << ISPH3A_AEWINSTART_WINSH_SHIFT;
	start |= conf->ver_win_start << ISPH3A_AEWINSTART_WINSV_SHIFT;

	blk = conf->blk_ver_win_start << ISPH3A_AEWINBLK_WINSV_SHIFT;
	blk |= ((conf->blk_win_height >> 1) - 1) << ISPH3A_AEWINBLK_WINH_SHIFT;

	subwin = ((conf->subsample_ver_inc >> 1) - 1) <<
		 ISPH3A_AEWSUBWIN_AEWINCV_SHIFT;
	subwin |= ((conf->subsample_hor_inc >> 1) - 1) <<
		  ISPH3A_AEWSUBWIN_AEWINCH_SHIFT;

	isp_reg_writel(aewb->isp, win1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1);
	isp_reg_writel(aewb->isp, start, OMAP3_ISP_IOMEM_H3A,
		       ISPH3A_AEWINSTART);
	isp_reg_writel(aewb->isp, blk, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK);
	isp_reg_writel(aewb->isp, subwin, OMAP3_ISP_IOMEM_H3A,
		       ISPH3A_AEWSUBWIN);
	isp_reg_clr_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
			ISPH3A_PCR_AEW_MASK, pcr);

	aewb->update = 0;
	aewb->config_counter += aewb->inc_config;
	aewb->inc_config = 0;
	aewb->buf_size = conf->buf_size;
}

static void h3a_aewb_enable(struct ispstat *aewb, int enable)
{
	if (enable) {
		isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
			    ISPH3A_PCR_AEW_EN);
		omap3isp_subclk_enable(aewb->isp, OMAP3_ISP_SUBCLK_AEWB);
	} else {
		isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
			    ISPH3A_PCR_AEW_EN);
		omap3isp_subclk_disable(aewb->isp, OMAP3_ISP_SUBCLK_AEWB);
	}
}

Annotation

Implementation Notes