driver: bma2x2: Remove tables for range/frequency

To save space, instead of using tables, use macros to convert
range/frequencies into register values.

BUG=b:73205042
BRANCH=none
TEST=Check we save space on Kevin. (184 bytes looking at __image_size in
kevin.RO.map).
Check on nami that range/bandwidth are set properly.

Change-Id: I193768be1f2e7325b986e8ccff25a7809bfb4096
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/959388
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
This commit is contained in:
Gwendal Grignou
2018-03-12 10:44:00 -07:00
committed by chrome-bot
parent 0778c50859
commit 7ce651d4ca
2 changed files with 37 additions and 82 deletions

View File

@@ -25,67 +25,11 @@
/* Number of times to attempt to enable sensor before giving up. */
#define SENSOR_ENABLE_ATTEMPTS 5
/*
* Struct for pairing an engineering value with the register value for a
* parameter.
*/
struct accel_param_pair {
int val; /* Value in engineering units. */
int reg; /* Corresponding register value. */
};
/* List of range values in +/-G's and their associated register values. */
static const struct accel_param_pair ranges[] = {
{2, BMA2x2_RANGE_2G},
{4, BMA2x2_RANGE_4G},
{8, BMA2x2_RANGE_8G},
{16, BMA2x2_RANGE_16G},
};
/* List of ODR values in mHz and their associated register values. */
static const struct accel_param_pair datarates[] = {
{781, BMA2x2_BW_7_81HZ},
{1563, BMA2x2_BW_15_63HZ},
{3125, BMA2x2_BW_31_25HZ},
{6250, BMA2x2_BW_62_50HZ},
{12500, BMA2x2_BW_125HZ},
{25000, BMA2x2_BW_250HZ},
{50000, BMA2x2_BW_500HZ},
{100000, BMA2x2_BW_1000HZ},
};
/**
* Find index into a accel_param_pair that matches the given engineering value
* passed in. The round_up flag is used to specify whether to round up or down.
* Note, this function always returns a valid index. If the request is
* outside the range of values, it returns the closest valid index.
*/
static int find_param_index(const int eng_val, const int round_up,
const struct accel_param_pair *pairs,
const int size)
{
int i = 0;
/* match first index */
if (eng_val <= pairs[i].val)
return i;
/* Linear search for index to match. */
while (++i < size) {
if (eng_val < pairs[i].val)
return round_up ? i : i - 1;
else if (eng_val == pairs[i].val)
return i;
}
return i - 1;
}
/**
* Read register from accelerometer.
*/
static int raw_read8(const int port, const int addr, const int reg,
int *data_ptr)
static inline int raw_read8(const int port, const int addr, const int reg,
int *data_ptr)
{
return i2c_read8(port, addr, reg, data_ptr);
}
@@ -93,7 +37,8 @@ static int raw_read8(const int port, const int addr, const int reg,
/**
* Write register from accelerometer.
*/
static int raw_write8(const int port, const int addr, const int reg, int data)
static inline int raw_write8(const int port, const int addr, const int reg,
int data)
{
return i2c_write8(port, addr, reg, data);
}
@@ -113,29 +58,28 @@ static int raw_read_multi(const int port, int addr, uint8_t reg,
static int set_range(const struct motion_sensor_t *s, int range, int rnd)
{
int ret, index, reg, range_val, reg_val, range_reg_val;
int ret, range_val, reg_val, range_reg_val;
struct bma2x2_accel_data *data = s->drv_data;
/* Find index for interface pair matching the specified range. */
index = find_param_index(range, rnd, ranges, ARRAY_SIZE(ranges));
reg = BMA2x2_RANGE_SELECT_ADDR;
range_val = ranges[index].reg;
range_val = BMA2x2_RANGE_TO_REG(range);
if ((BMA2x2_RANGE_TO_REG(range_val) < range) && rnd)
range_val = BMA2x2_RANGE_TO_REG(range * 2);
mutex_lock(s->mutex);
/* Determine the new value of control reg and attempt to write it. */
ret = raw_read8(s->port, s->addr, reg, &range_reg_val);
ret = raw_read8(s->port, s->addr, BMA2x2_RANGE_SELECT_ADDR,
&range_reg_val);
if (ret != EC_SUCCESS) {
mutex_unlock(s->mutex);
return ret;
}
reg_val = (range_reg_val & ~BMA2x2_RANGE_SELECT_MSK) | range_val;
ret = raw_write8(s->port, s->addr, reg, reg_val);
ret = raw_write8(s->port, s->addr, BMA2x2_RANGE_SELECT_ADDR, reg_val);
/* If successfully written, then save the range. */
if (ret == EC_SUCCESS)
data->sensor_range = index;
data->sensor_range = BMA2x2_REG_TO_RANGE(range_val);
mutex_unlock(s->mutex);
@@ -146,7 +90,7 @@ static int get_range(const struct motion_sensor_t *s)
{
struct bma2x2_accel_data *data = s->drv_data;
return ranges[data->sensor_range].val;
return data->sensor_range;
}
static int set_resolution(const struct motion_sensor_t *s, int res, int rnd)
@@ -162,30 +106,28 @@ static int get_resolution(const struct motion_sensor_t *s)
static int set_data_rate(const struct motion_sensor_t *s, int rate, int rnd)
{
int ret, index, odr_val, odr_reg_val, reg_val, reg;
int ret, odr_val, odr_reg_val, reg_val;
struct bma2x2_accel_data *data = s->drv_data;
/* Find index for interface pair matching the specified rate. */
index = find_param_index(rate, rnd, datarates, ARRAY_SIZE(datarates));
odr_val = datarates[index].reg;
reg = BMA2x2_BW_SELECT_ADDR;
odr_val = BMA2x2_BW_TO_REG(rate);
if ((BMA2x2_REG_TO_BW(odr_val) < rate) && rnd)
odr_val = BMA2x2_BW_TO_REG(rate * 2);
mutex_lock(s->mutex);
/* Determine the new value of control reg and attempt to write it. */
ret = raw_read8(s->port, s->addr, reg, &odr_reg_val);
ret = raw_read8(s->port, s->addr, BMA2x2_BW_SELECT_ADDR, &odr_reg_val);
if (ret != EC_SUCCESS) {
mutex_unlock(s->mutex);
return ret;
}
reg_val = (odr_reg_val & ~BMA2x2_BW_MSK) | odr_val;
/* Set output data rate. */
ret = raw_write8(s->port, s->addr, reg, reg_val);
ret = raw_write8(s->port, s->addr, BMA2x2_BW_SELECT_ADDR, reg_val);
/* If successfully written, then save the new data rate. */
if (ret == EC_SUCCESS)
data->sensor_datarate = index;
data->sensor_datarate = BMA2x2_REG_TO_BW(odr_val);
mutex_unlock(s->mutex);
return ret;
@@ -195,7 +137,7 @@ static int get_data_rate(const struct motion_sensor_t *s)
{
struct bma2x2_accel_data *data = s->drv_data;
return datarates[data->sensor_datarate].val;
return data->sensor_datarate;
}
static int set_offset(const struct motion_sensor_t *s, const int16_t *offset,

View File

@@ -14,13 +14,10 @@ enum bma2x2_accel {
};
struct bma2x2_accel_data {
/* Note, the following are indicies into their respective tables. */
/* Current range of accelerometer. */
int sensor_range;
/* Current output data rate of accelerometer. */
int sensor_datarate;
/* Current resolution of accelerometer. */
int sensor_resolution;
int16_t offset[3];
};
@@ -79,6 +76,14 @@ extern const struct accelgyro_drv bma2x2_accel_drv;
#define BMA2x2_RANGE_8G 8
#define BMA2x2_RANGE_16G 12
#define BMA2x2_RANGE_TO_REG(_range) \
((_range) < 8 ? BMA2x2_RANGE_2G + ((_range) / 4) * 2 : \
BMA2x2_RANGE_8G + ((_range) / 16) * 4)
#define BMA2x2_REG_TO_RANGE(_reg) \
((_reg) < BMA2x2_RANGE_8G ? 2 + (_reg) - BMA2x2_RANGE_2G : \
8 + ((_reg) - BMA2x2_RANGE_8G) * 2)
#define BMA2x2_BW_SELECT_ADDR 0x10
#define BMA2x2_BW_MSK 0x1F
#define BMA2x2_BW_7_81HZ 0x08 /* LowPass 7.81HZ */
@@ -90,6 +95,14 @@ extern const struct accelgyro_drv bma2x2_accel_drv;
#define BMA2x2_BW_500HZ 0x0E /* LowPass 500HZ */
#define BMA2x2_BW_1000HZ 0x0F /* LowPass 1000HZ */
#define BMA2x2_BW_TO_REG(_bw) \
((_bw) < 125000 ? BMA2x2_BW_7_81HZ + __fls((_bw) / 7810) : \
BMA2x2_BW_125HZ + __fls((_bw) / 125000))
#define BMA2x2_REG_TO_BW(_reg) \
((_reg) < BMA2x2_BW_125HZ ? 7810 << ((_reg) - BMA2x2_BW_7_81HZ) : \
125000 << ((_reg) - BMA2x2_BW_125HZ))
#define BMA2x2_MODE_CTRL_ADDR 0x11
#define BMA2x2_LOW_NOISE_CTRL_ADDR 0x12
#define BMA2x2_DATA_CTRL_ADDR 0x13