genesys: Use single code path for gain code calculation

pixma-axis-driver
Povilas Kanapickas 2020-03-14 23:19:27 +02:00
rodzic e0bec6723d
commit 233cb4bd5a
8 zmienionych plików z 102 dodań i 73 usunięć

Wyświetl plik

@ -1559,18 +1559,15 @@ void CommandSetGl124::coarse_gain_calibration(Genesys_Device* dev, const Genesys
total += image.get_raw_channel(x, 0, ch);
}
total /= width / 2;
float target_value = sensor.gain_white_ref * coeff;
float curr_output = total / (width / 2);
gain[ch] = (static_cast<float>(sensor.gain_white_ref) * coeff) / total;
std::uint8_t out_gain = compute_frontend_gain(curr_output, target_value,
dev->frontend.layout.type);
dev->frontend.set_gain(ch, out_gain);
/* turn logical gain value into gain code, checking for overflow */
code = static_cast<int>(283 - 208 / gain[ch]);
code = clamp(code, 0, 255);
dev->frontend.set_gain(ch, code);
DBG(DBG_proc, "%s: channel %d, total=%d, gain = %f, setting:%d\n", __func__, ch,
static_cast<unsigned>(total),
gain[ch], dev->frontend.get_gain(ch));
DBG(DBG_proc, "%s: channel %d, curr=%f, target=%f, out_gain:%d\n", __func__, ch,
curr_output, target_value, out_gain);
}
if (dev->model->is_cis) {

Wyświetl plik

@ -2950,7 +2950,6 @@ void CommandSetGl841::coarse_gain_calibration(Genesys_Device* dev, const Genesys
Genesys_Register_Set& regs, int dpi) const
{
DBG_HELPER_ARGS(dbg, "dpi=%d", dpi);
float gain[3];
int lines=1;
// feed to white strip if needed
@ -3022,45 +3021,27 @@ void CommandSetGl841::coarse_gain_calibration(Genesys_Device* dev, const Genesys
}
}
gain[ch] = 65535.0f / max;
float curr_output = max;
float target_value = 65535.0f;
uint8_t out_gain = 0;
std::uint8_t out_gain = compute_frontend_gain(curr_output, target_value,
dev->frontend.layout.type);
if (dev->model->adc_id == AdcId::CANON_LIDE_35 ||
dev->model->adc_id == AdcId::WOLFSON_XP300 ||
dev->model->adc_id == AdcId::WOLFSON_DSM600)
{
gain[ch] *= 0.69f; // seems we don't get the real maximum. empirically derived
if (283 - 208 / gain[ch] > 255) {
out_gain = 255;
} else if (283 - 208 / gain[ch] < 0) {
out_gain = 0;
} else {
out_gain = static_cast<std::uint8_t>(283 - 208 / gain[ch]);
}
} else if (dev->model->adc_id == AdcId::CANON_LIDE_80) {
out_gain = static_cast<std::uint8_t>(gain[ch] * 12);
}
dev->frontend.set_gain(ch, out_gain);
DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, ch, max,
gain[ch], out_gain);
}
DBG(DBG_proc, "%s: channel %d, curr=%f, target=%f, out_gain:%d\n", __func__, ch,
curr_output, target_value, out_gain);
for (unsigned j = 0; j < channels; j++) {
if (gain[j] > 30) {
DBG (DBG_error0, "**********************************************\n");
DBG (DBG_error0, "**********************************************\n");
DBG (DBG_error0, "**** ****\n");
DBG (DBG_error0, "**** Extremely low Brightness detected. ****\n");
DBG (DBG_error0, "**** Check the scanning head is ****\n");
DBG (DBG_error0, "**** unlocked and moving. ****\n");
DBG (DBG_error0, "**** ****\n");
DBG (DBG_error0, "**********************************************\n");
DBG (DBG_error0, "**********************************************\n");
if (target_value / curr_output > 30) {
DBG(DBG_error0, "****************************************\n");
DBG(DBG_error0, "* *\n");
DBG(DBG_error0, "* Extremely low Brightness detected. *\n");
DBG(DBG_error0, "* Check the scanning head is *\n");
DBG(DBG_error0, "* unlocked and moving. *\n");
DBG(DBG_error0, "* *\n");
DBG(DBG_error0, "****************************************\n");
throw SaneException(SANE_STATUS_JAMMED, "scanning head is locked");
}
}
if (dev->model->is_cis) {

Wyświetl plik

@ -1332,8 +1332,8 @@ void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys
Genesys_Register_Set& regs, int dpi) const
{
DBG_HELPER(dbg);
float gain[3],coeff;
int code, lines;
float coeff;
int lines;
DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi);
@ -1413,17 +1413,15 @@ void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys
total += image.get_raw_channel(x, 0, ch);
}
total /= width / 2;
float target_value = sensor.gain_white_ref * coeff;
float curr_output = total / (width / 2);
gain[ch] = (static_cast<float>(sensor.gain_white_ref) * coeff) / total;
std::uint8_t out_gain = compute_frontend_gain(curr_output, target_value,
dev->frontend.layout.type);
dev->frontend.set_gain(ch, out_gain);
/* turn logical gain value into gain code, checking for overflow */
code = static_cast<int>(283 - 208 / gain[ch]);
code = clamp(code, 0, 255);
dev->frontend.set_gain(ch, code);
DBG(DBG_proc, "%s: channel %d, total=%d, gain = %f, setting:%d\n", __func__, ch,
static_cast<unsigned>(total), gain[ch], dev->frontend.get_gain(ch));
DBG(DBG_proc, "%s: channel %d, curr=%f, target=%f, out_gain:%d\n", __func__, ch,
curr_output, target_value, out_gain);
}
if (dev->model->is_cis) {

Wyświetl plik

@ -1373,8 +1373,8 @@ void CommandSetGl847::coarse_gain_calibration(Genesys_Device* dev, const Genesys
Genesys_Register_Set& regs, int dpi) const
{
DBG_HELPER_ARGS(dbg, "dpi = %d", dpi);
float gain[3],coeff;
int code, lines;
float coeff;
int lines;
// no gain nor offset for AKM AFE
uint8_t reg04 = dev->interface->read_register(REG_0x04);
@ -1452,17 +1452,15 @@ void CommandSetGl847::coarse_gain_calibration(Genesys_Device* dev, const Genesys
total += image.get_raw_channel(x, 0, ch);
}
total /= width / 2;
float target_value = sensor.gain_white_ref * coeff;
float curr_output = total / (width / 2);
gain[ch] = (static_cast<float>(sensor.gain_white_ref) * coeff) / total;
std::uint8_t out_gain = compute_frontend_gain(curr_output, target_value,
dev->frontend.layout.type);
dev->frontend.set_gain(ch, out_gain);
/* turn logical gain value into gain code, checking for overflow */
code = static_cast<int>(283 - 208 / gain[ch]);
code = clamp(code, 0, 255);
dev->frontend.set_gain(ch, code);
DBG(DBG_proc, "%s: channel %d, total=%d, gain = %f, setting:%d\n", __func__, ch,
static_cast<unsigned>(total), gain[ch], dev->frontend.get_gain(ch));
DBG(DBG_proc, "%s: channel %d, curr=%f, target=%f, out_gain:%d\n", __func__, ch,
curr_output, target_value, out_gain);
}
if (dev->model->is_cis) {

Wyświetl plik

@ -1335,6 +1335,32 @@ std::uint8_t compute_frontend_gain_wolfson(float value, float target_value)
return clamp(code, 0, 255);
}
std::uint8_t compute_frontend_gain_lide_80(float value, float target_value)
{
int code = static_cast<int>((target_value / value) * 12);
return clamp(code, 0, 255);
}
std::uint8_t compute_frontend_gain_wolfson_gl841(float value, float target_value)
{
// this code path is similar to what generic wolfson code path uses and uses similar constants,
// but is likely incorrect.
float inv_gain = target_value / value;
inv_gain *= 0.69f;
int code = static_cast<int>(283 - 208 / inv_gain);
return clamp(code, 0, 255);
}
std::uint8_t compute_frontend_gain_wolfson_gl846_gl847_gl124(float value, float target_value)
{
// this code path is similar to what generic wolfson code path uses and uses similar constants,
// but is likely incorrect.
float inv_gain = target_value / value;
int code = static_cast<int>(283 - 208 / inv_gain);
return clamp(code, 0, 255);
}
std::uint8_t compute_frontend_gain_analog_devices(float value, float target_value)
{
/* The flow of data through the frontend ADC is as follows (see e.g. AD9826 datasheet)
@ -1359,14 +1385,23 @@ std::uint8_t compute_frontend_gain_analog_devices(float value, float target_valu
std::uint8_t compute_frontend_gain(float value, float target_value,
FrontendType frontend_type)
{
if (frontend_type == FrontendType::WOLFSON) {
switch (frontend_type) {
case FrontendType::WOLFSON:
return compute_frontend_gain_wolfson(value, target_value);
}
if (frontend_type == FrontendType::ANALOG_DEVICES) {
case FrontendType::ANALOG_DEVICES:
return compute_frontend_gain_analog_devices(value, target_value);
}
case FrontendType::CANON_LIDE_80:
return compute_frontend_gain_lide_80(value, target_value);
case FrontendType::WOLFSON_GL841:
return compute_frontend_gain_wolfson_gl841(value, target_value);
case FrontendType::WOLFSON_GL846:
case FrontendType::WOLFSON_GL847:
case FrontendType::WOLFSON_GL124:
return compute_frontend_gain_wolfson_gl846_gl847_gl124(value, target_value);
default:
throw SaneException("Unknown frontend to compute gain for");
}
}
/** @brief initialize device
* Initialize backend and ASIC : registers, motor tables, and gamma tables

Wyświetl plik

@ -64,6 +64,11 @@ std::ostream& operator<<(std::ostream& out, const FrontendType& type)
case FrontendType::UNKNOWN: out << "UNKNOWN"; break;
case FrontendType::WOLFSON: out << "WOLFSON"; break;
case FrontendType::ANALOG_DEVICES: out << "ANALOG_DEVICES"; break;
case FrontendType::CANON_LIDE_80: out << "CANON_LIDE_80"; break;
case FrontendType::WOLFSON_GL841: out << "WOLFSON_GL841"; break;
case FrontendType::WOLFSON_GL846: out << "WOLFSON_GL846"; break;
case FrontendType::WOLFSON_GL847: out << "WOLFSON_GL847"; break;
case FrontendType::WOLFSON_GL124: out << "WOLFSON_GL124"; break;
default: out << "(unknown value)";
}
return out;

Wyświetl plik

@ -114,9 +114,14 @@ std::ostream& operator<<(std::ostream& out, const StaggerConfig& config);
enum class FrontendType : unsigned
{
UNKNOWN,
UNKNOWN = 0,
WOLFSON,
ANALOG_DEVICES
ANALOG_DEVICES,
CANON_LIDE_80,
WOLFSON_GL841, // old code path, likely wrong calculation
WOLFSON_GL846, // old code path, likely wrong calculation
WOLFSON_GL847, // old code path, likely wrong calculation
WOLFSON_GL124, // old code path, likely wrong calculation
};
inline void serialize(std::istream& str, FrontendType& x)

Wyświetl plik

@ -198,6 +198,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::CANON_LIDE_35;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL841;
fe.regs = {
{ 0x00, 0x00 },
{ 0x01, 0x3d },
@ -242,6 +243,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::WOLFSON_XP300;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL841;
fe.regs = {
{ 0x00, 0x00 },
{ 0x01, 0x35 },
@ -286,6 +288,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::WOLFSON_DSM600;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL841;
fe.regs = {
{ 0x00, 0x00 },
{ 0x01, 0x35 },
@ -308,6 +311,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::CANON_LIDE_200;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL847;
fe.regs = {
{ 0x00, 0x9d },
{ 0x01, 0x91 },
@ -330,6 +334,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::CANON_LIDE_700F;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL847;
fe.regs = {
{ 0x00, 0x9d },
{ 0x01, 0x9e },
@ -396,6 +401,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::CANON_LIDE_110;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL124;
fe.regs = {
{ 0x00, 0x80 },
{ 0x01, 0x8a },
@ -422,6 +428,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::CANON_LIDE_120;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL124;
fe.regs = {
{ 0x00, 0x80 },
{ 0x01, 0xa3 },
@ -583,6 +590,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::IMG101;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL846;
fe.regs = {
{ 0x00, 0x78 },
{ 0x01, 0xf0 },
@ -605,6 +613,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::PLUSTEK_OPTICBOOK_3800;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::WOLFSON_GL846;
fe.regs = {
{ 0x00, 0x78 },
{ 0x01, 0xf0 },
@ -631,6 +640,7 @@ void genesys_init_frontend_tables()
fe = Genesys_Frontend();
fe.id = AdcId::CANON_LIDE_80;
fe.layout = wolfson_layout;
fe.layout.type = FrontendType::CANON_LIDE_80;
fe.regs = {
{ 0x00, 0x70 },
{ 0x01, 0x16 },