Commit fe652254 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

media: ccs: Read ireal numbers correctly

Some limit values are available in q16.q16 format, referred to as 32-bit
unsigned ireal in CCS. Read these correctly.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 5017f8b4
...@@ -126,8 +126,8 @@ void ccs_replace_limit(struct ccs_sensor *sensor, ...@@ -126,8 +126,8 @@ void ccs_replace_limit(struct ccs_sensor *sensor,
ccs_assign_limit(ptr, ccs_reg_width(linfo->reg), val); ccs_assign_limit(ptr, ccs_reg_width(linfo->reg), val);
} }
static u32 ccs_get_limit(struct ccs_sensor *sensor, u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit,
unsigned int limit, unsigned int offset) unsigned int offset)
{ {
void *ptr; void *ptr;
u32 val; u32 val;
...@@ -155,12 +155,6 @@ static u32 ccs_get_limit(struct ccs_sensor *sensor, ...@@ -155,12 +155,6 @@ static u32 ccs_get_limit(struct ccs_sensor *sensor,
return ccs_reg_conv(sensor, ccs_limits[limit].reg, val); return ccs_reg_conv(sensor, ccs_limits[limit].reg, val);
} }
#define CCS_LIM(sensor, limit) \
ccs_get_limit(sensor, CCS_L_##limit, 0)
#define CCS_LIM_AT(sensor, limit, offset) \
ccs_get_limit(sensor, CCS_L_##limit, CCS_L_##limit##_OFFSET(offset))
static int ccs_read_all_limits(struct ccs_sensor *sensor) static int ccs_read_all_limits(struct ccs_sensor *sensor)
{ {
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include "ccs.h" #include "ccs.h"
#include "ccs-limits.h"
static uint32_t float_to_u32_mul_1000000(struct i2c_client *client, static uint32_t float_to_u32_mul_1000000(struct i2c_client *client,
uint32_t phloat) uint32_t phloat)
...@@ -143,12 +144,30 @@ unsigned int ccs_reg_width(u32 reg) ...@@ -143,12 +144,30 @@ unsigned int ccs_reg_width(u32 reg)
return sizeof(uint8_t); return sizeof(uint8_t);
} }
static u32 ireal32_to_u32_mul_1000000(struct i2c_client *client, u32 val)
{
if (val >> 10 > U32_MAX / 15625) {
dev_warn(&client->dev, "value %u overflows!\n", val);
return U32_MAX;
}
return ((val >> 10) * 15625) +
(val & GENMASK(9, 0)) * 15625 / 1024;
}
u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val) u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val)
{ {
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
if (reg & CCS_FL_FLOAT_IREAL) if (reg & CCS_FL_FLOAT_IREAL) {
val = float_to_u32_mul_1000000(client, val); if (CCS_LIM(sensor, CLOCK_CAPA_TYPE_CAPABILITY) &
CCS_CLOCK_CAPA_TYPE_CAPABILITY_IREAL)
val = ireal32_to_u32_mul_1000000(client, val);
else
val = float_to_u32_mul_1000000(client, val);
} else if (reg & CCS_FL_IREAL) {
val = ireal32_to_u32_mul_1000000(client, val);
}
return val; return val;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <media/v4l2-subdev.h> #include <media/v4l2-subdev.h>
#include "ccs-data.h" #include "ccs-data.h"
#include "ccs-limits.h"
#include "ccs-quirk.h" #include "ccs-quirk.h"
#include "ccs-regs.h" #include "ccs-regs.h"
#include "ccs-reg-access.h" #include "ccs-reg-access.h"
...@@ -50,6 +51,12 @@ ...@@ -50,6 +51,12 @@
#define CCS_DFL_I2C_ADDR (0x20 >> 1) /* Default I2C Address */ #define CCS_DFL_I2C_ADDR (0x20 >> 1) /* Default I2C Address */
#define CCS_ALT_I2C_ADDR (0x6e >> 1) /* Alternate I2C Address */ #define CCS_ALT_I2C_ADDR (0x6e >> 1) /* Alternate I2C Address */
#define CCS_LIM(sensor, limit) \
ccs_get_limit(sensor, CCS_L_##limit, 0)
#define CCS_LIM_AT(sensor, limit, offset) \
ccs_get_limit(sensor, CCS_L_##limit, CCS_L_##limit##_OFFSET(offset))
/* /*
* Sometimes due to board layout considerations the camera module can be * Sometimes due to board layout considerations the camera module can be
* mounted rotated. The typical rotation used is 180 degrees which can be * mounted rotated. The typical rotation used is 180 degrees which can be
...@@ -277,5 +284,7 @@ struct ccs_sensor { ...@@ -277,5 +284,7 @@ struct ccs_sensor {
void ccs_replace_limit(struct ccs_sensor *sensor, void ccs_replace_limit(struct ccs_sensor *sensor,
unsigned int limit, unsigned int offset, u32 val); unsigned int limit, unsigned int offset, u32 val);
u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit,
unsigned int offset);
#endif /* __CCS_H__ */ #endif /* __CCS_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment