diff --git a/src/ipa/libipa/lsc_base.h b/src/ipa/libipa/lsc_base.h
index b0b9b3b0712d..386cac55be34 100644
--- a/src/ipa/libipa/lsc_base.h
+++ b/src/ipa/libipa/lsc_base.h
@@ -26,7 +26,7 @@ namespace ipa {
 
 namespace lsc {
 
-using Components = std::map<std::string, std::vector<uint16_t>>;
+using Components = std::map<std::string, std::vector<float>>;
 using ComponentsMap = std::map<unsigned int, Components>;
 
 } /* namespace lsc */
diff --git a/src/ipa/libipa/lsc_polynomial.cpp b/src/ipa/libipa/lsc_polynomial.cpp
index c61c85fbf2b2..e31a63e06cc8 100644
--- a/src/ipa/libipa/lsc_polynomial.cpp
+++ b/src/ipa/libipa/lsc_polynomial.cpp
@@ -218,7 +218,7 @@ LscPolynomial::sampleForCrop(const Rectangle &cropRectangle,
 	return components;
 }
 
-std::vector<uint16_t>
+std::vector<float>
 LscPolynomial::samplePolynomial(const lsc::Polynomial &poly,
 				Span<const double> xPositions,
 				Span<const double> yPositions,
@@ -229,7 +229,7 @@ LscPolynomial::samplePolynomial(const lsc::Polynomial &poly,
 	double y0 = cropRectangle.y / m;
 	double w = cropRectangle.width / m;
 	double h = cropRectangle.height / m;
-	std::vector<uint16_t> samples;
+	std::vector<float> samples;
 
 	samples.reserve(xPositions.size() * yPositions.size());
 
@@ -237,16 +237,9 @@ LscPolynomial::samplePolynomial(const lsc::Polynomial &poly,
 		for (double x : xPositions) {
 			double xp = x0 + x * w;
 			double yp = y0 + y * h;
-			/*
-			 * The hardware uses 2.10 fixed point format and limits
-			 * the legal values to [1..3.999]. Scale and clamp the
-			 * sampled value accordingly.
-			 */
-			int v = static_cast<int>(
-				poly.sampleAtNormalizedPixelPos(xp, yp) *
-				1024);
-			v = std::clamp(v, 1024, 4095);
-			samples.push_back(v);
+
+			samples.push_back(static_cast<float>
+					 (poly.sampleAtNormalizedPixelPos(xp, yp)));
 		}
 	}
 	return samples;
diff --git a/src/ipa/libipa/lsc_polynomial.h b/src/ipa/libipa/lsc_polynomial.h
index 6d19e46a50b7..8d526531075b 100644
--- a/src/ipa/libipa/lsc_polynomial.h
+++ b/src/ipa/libipa/lsc_polynomial.h
@@ -65,10 +65,10 @@ public:
 		      std::vector<double> xPos, std::vector<double> yPos) override;
 
 private:
-	std::vector<uint16_t> samplePolynomial(const lsc::Polynomial &poly,
-					       Span<const double> xPositions,
-					       Span<const double> yPositions,
-					       const Rectangle &cropRectangle);
+	std::vector<float> samplePolynomial(const lsc::Polynomial &poly,
+					    Span<const double> xPositions,
+					    Span<const double> yPositions,
+					    const Rectangle &cropRectangle);
 	PolynomialComponentsMap lscData_;
 };
 
diff --git a/src/ipa/libipa/lsc_table.cpp b/src/ipa/libipa/lsc_table.cpp
index 92e24bc5160a..33f6182de1bd 100644
--- a/src/ipa/libipa/lsc_table.cpp
+++ b/src/ipa/libipa/lsc_table.cpp
@@ -82,15 +82,15 @@ int LscTable::parseLscComponent(const ValueNode &yamlSet,
 	return 0;
 }
 
-std::vector<uint16_t> LscTable::parseTable(const ValueNode &tuningData,
+std::vector<float> LscTable::parseTable(const ValueNode &tuningData,
 					   const char *prop,
 					   unsigned int numHSamples,
 					   unsigned int numVSamples)
 {
 	unsigned int lscNumSamples = numHSamples * numVSamples;
 
-	std::vector<uint16_t> table =
-		tuningData[prop].get<std::vector<uint16_t>>().value_or(utils::defopt);
+	std::vector<float> table =
+		tuningData[prop].get<std::vector<float>>().value_or(utils::defopt);
 	if (table.size() != lscNumSamples) {
 		LOG(LscTable, Error)
 			<< "Invalid '" << prop << "' values: expected "
diff --git a/src/ipa/libipa/lsc_table.h b/src/ipa/libipa/lsc_table.h
index a33208761c15..6d9b0c692b7f 100644
--- a/src/ipa/libipa/lsc_table.h
+++ b/src/ipa/libipa/lsc_table.h
@@ -42,7 +42,7 @@ public:
 private:
 	int parseLscComponent(const ValueNode &yamlSet,
 			      unsigned int ct, const LscDescriptor &descriptor);
-	std::vector<uint16_t> parseTable(const ValueNode &tuningData,
+	std::vector<float> parseTable(const ValueNode &tuningData,
 					 const char *prop,
 					 unsigned int numHSamples,
 					 unsigned int numVSamples);
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp
index 7a95bfcfb93a..dba1a01118ee 100644
--- a/src/ipa/rkisp1/algorithms/lsc.cpp
+++ b/src/ipa/rkisp1/algorithms/lsc.cpp
@@ -177,14 +177,32 @@ void LensShadingCorrection::setParameters(rkisp1_cif_isp_lsc_config &config)
 void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,
 				      const lsc::Components &set)
 {
-	const auto &r = set.at("r");
-	std::copy(r.begin(), r.end(), &config.r_data_tbl[0][0]);
-	const auto &gr = set.at("gr");
-	std::copy(gr.begin(), gr.end(), &config.gr_data_tbl[0][0]);
-	const auto &gb = set.at("gb");
-	std::copy(gb.begin(), gb.end(), &config.gb_data_tbl[0][0]);
-	const auto &b = set.at("b");
-	std::copy(b.begin(), b.end(), &config.b_data_tbl[0][0]);
+	/*
+	 * The hardware uses 2.10 fixed point format and limits the legal values
+	 * to [1..3.999]. Scale and clamp the sampled values accordingly.
+	 */
+	std::vector<uint16_t> regs;
+	regs.reserve(RKISP1_CIF_ISP_LSC_SAMPLES_MAX *
+		     RKISP1_CIF_ISP_LSC_SAMPLES_MAX);
+
+	for (const float &f : set.at("r"))
+		regs.emplace_back(std::clamp(static_cast<int>(f * 1024), 1024, 4095));
+	std::copy(regs.begin(), regs.end(), &config.r_data_tbl[0][0]);
+
+	regs = {};
+	for (const float &f : set.at("gr"))
+		regs.emplace_back(std::clamp(static_cast<int>(f * 1024), 1024, 4095));
+	std::copy(regs.begin(), regs.end(), &config.gr_data_tbl[0][0]);
+
+	regs = {};
+	for (const float &f : set.at("gb"))
+		regs.emplace_back(std::clamp(static_cast<int>(f * 1024), 1024, 4095));
+	std::copy(regs.begin(), regs.end(), &config.gb_data_tbl[0][0]);
+
+	regs = {};
+	for (const float &f : set.at("b"))
+		regs.emplace_back(std::clamp(static_cast<int>(f * 1024), 1024, 4095));
+	std::copy(regs.begin(), regs.end(), &config.b_data_tbl[0][0]);
 }
 
 /**
