summaryrefslogtreecommitdiff
path: root/include/linux/media-bus-format.h
AgeCommit message (Collapse)Author
2019-10-28include: linux: Update headers to Linux v5.2Jacopo Mondi
Update headers to Linux v5.2. The Rockchip ISP1 formats that were added manually in commit 97dce7a13fa3 ("include: linux: Add rkisp1 kernel header and format definitions") are kept. Otherwise the headers come straight from the upstream kernel. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-01-17include: linux: Import V4L2 uAPI headers from Linux v4.19Kieran Bingham
Import the following files from the Linux UAPI to keep our V4L2 interface in sync: media-bus-format.h v4l2-common.h v4l2-controls.h v4l2-mediabus.h v4l2-subdev.h videodev2.h Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
rithms/gsl.cpp?h=jmondi/lc-compliance-cros&id=ef447647b6b71fc19a9560352afe4665711150ac'>gsl.cpp
blob: 2fd1a23d3a9bc119dfc868d7fdd21ada190483c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2021-2022, Ideas On Board
 *
 * gsl.cpp - RkISP1 Gamma Sensor Linearization control
 */

#include "gsl.h"

#include <libcamera/base/log.h>
#include <libcamera/base/utils.h>

#include "libcamera/internal/yaml_parser.h"

#include "linux/rkisp1-config.h"

/**
 * \file gsl.h
 */

namespace libcamera {

namespace ipa::rkisp1::algorithms {

/**
 * \class GammaSensorLinearization
 * \brief RkISP1 Gamma Sensor Linearization control
 *
 * This algorithm linearizes the sensor output to compensate the sensor
 * non-linearities by applying piecewise linear functions to the red, green and
 * blue channels.
 *
 * The curves are specified in the tuning data and defined using 17 points.
 *
 * - The X coordinates are expressed using 16 intervals, with the first point
 *   at X coordinate 0. Each interval is expressed as a 2-bit value DX (from
 *   GAMMA_DX_1 to GAMMA_DX_16), stored in the RKISP1_CIF_ISP_GAMMA_DX_LO and
 *   RKISP1_CIF_ISP_GAMMA_DX_HI registers. The real interval is equal to
 *   \f$2^{dx+4}\f$. X coordinates are shared between the red, green and blue
 *   curves.
 *
 * - The Y coordinates are specified as 17 values separately for the
 *   red, green and blue channels, with a 12-bit resolution. Each value must be
 *   in the [-2048, 2047] range compared to the previous value.
 */

LOG_DEFINE_CATEGORY(RkISP1Gsl)

static constexpr unsigned int kDegammaXIntervals = 16;

GammaSensorLinearization::GammaSensorLinearization()
	: initialized_(false)
{
}

/**
 * \copydoc libcamera::ipa::Algorithm::init
 */
int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,
				   const YamlObject &tuningData)
{
	std::vector<uint16_t> xIntervals =
		tuningData["x-intervals"].getList<uint16_t>().value_or(utils::defopt);
	if (xIntervals.size() != kDegammaXIntervals) {
		LOG(RkISP1Gsl, Error)
			<< "Invalid 'x' coordinates: expected "
			<< kDegammaXIntervals << " elements, got "
			<< xIntervals.size();

		return -EINVAL;
	}

	/* Compute gammaDx_ intervals from xIntervals values */
	gammaDx_[0] = 0;
	gammaDx_[1] = 0;
	for (unsigned int i = 0; i < kDegammaXIntervals; ++i)
		gammaDx_[i / 8] |= (xIntervals[i] & 0x07) << ((i % 8) * 4);

	const YamlObject &yObject = tuningData["y"];
	if (!yObject.isDictionary()) {
		LOG(RkISP1Gsl, Error)
			<< "Issue while parsing 'y' in tuning file: "
			<< "entry must be a dictionary";
		return -EINVAL;
	}

	curveYr_ = yObject["red"].getList<uint16_t>().value_or(utils::defopt);
	if (curveYr_.size() != RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE) {
		LOG(RkISP1Gsl, Error)
			<< "Invalid 'y:red' coordinates: expected "
			<< RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE
			<< " elements, got " << curveYr_.size();
		return -EINVAL;
	}

	curveYg_ = yObject["green"].getList<uint16_t>().value_or(utils::defopt);
	if (curveYg_.size() != RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE) {
		LOG(RkISP1Gsl, Error)
			<< "Invalid 'y:green' coordinates: expected "
			<< RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE
			<< " elements, got " << curveYg_.size();
		return -EINVAL;
	}

	curveYb_ = yObject["blue"].getList<uint16_t>().value_or(utils::defopt);
	if (curveYb_.size() != RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE) {
		LOG(RkISP1Gsl, Error)
			<< "Invalid 'y:blue' coordinates: expected "
			<< RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE
			<< " elements, got " << curveYb_.size();
		return -EINVAL;
	}

	initialized_ = true;
	return 0;
}

/**
 * \copydoc libcamera::ipa::Algorithm::prepare
 */
void GammaSensorLinearization::prepare(IPAContext &context,
				       rkisp1_params_cfg *params)
{
	if (context.frameContext.frameCount > 0)
		return;

	if (!initialized_)
		return;

	params->others.sdg_config.xa_pnts.gamma_dx0 = gammaDx_[0];
	params->others.sdg_config.xa_pnts.gamma_dx1 = gammaDx_[1];

	std::copy(curveYr_.begin(), curveYr_.end(),
		  params->others.sdg_config.curve_r.gamma_y);
	std::copy(curveYg_.begin(), curveYg_.end(),
		  params->others.sdg_config.curve_g.gamma_y);
	std::copy(curveYb_.begin(), curveYb_.end(),
		  params->others.sdg_config.curve_b.gamma_y);

	params->module_en_update |= RKISP1_CIF_ISP_MODULE_SDG;
	params->module_ens |= RKISP1_CIF_ISP_MODULE_SDG;
	params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_SDG;
}

REGISTER_IPA_ALGORITHM(GammaSensorLinearization, "GammaSensorLinearization")

} /* namespace ipa::rkisp1::algorithms */

} /* namespace libcamera */