Hi,
This patchset contains a collection of new features and fixes for
the bh1770glc driver for the BH1770 and SFH7770 proximity
and ambient light sensor device.
In few words this is what it brings:
- /dev/input/event interface
- removal obsolete and wrong parameters
- new relevant parameters for glass attenuation and glass
factor, lux compensation due to the LED cover or ink
- improvments of the threshold usage
- corrections of the device rates and default LED current
- general code cleanup
These patches have been applied on top of mainline master, but
they could be easily applied on top of any branch since they
don't affect any core code.
Thanks,
Andi
Andi Shyti (7):
bh1770glc: added input device interface
bh1770glc: removed proximity adjustement
bh1770glc: split read result function
bh1770glc: logic change in the proximity read
bh1770glc: use min_t instead of min
bh1770glc: use kstrtoul instead of strict_strtoul
bh1770glc: removed lux_read_raw_result() function
Onur Atilla (12):
bh1770glc: different glass attenuation parameters
bh1770glc: lux0_glass_factor & lux0_comp_factor on sysfs
bh1770glc: Added raw lux output file for ALS to sysfs
bh1770glc: Removed obsolete offset settings from SFH7770 code
bh1770glc: Introduced dynamic threshold
bh1770glc: Code cleaning and aligning in source code
bh1770glc: Modified the neutral glass attenuation value
bh1770glc: Modified scaler variable
bh1770glc: Added sanity check for scf
bh1770glc: Implemented switch for interrupt operation
bh1770glc: Corrected proximity sensor rates
bh1770glc: Proximity sensor LED current update
drivers/misc/bh1770glc.c | 411 +++++++++++++++++++++++++++--------------
include/linux/i2c/bh1770glc.h | 30 +--
2 files changed, 289 insertions(+), 152 deletions(-)
--
1.7.10.4
From: Onur Atilla <[email protected]>
The rate table of the proximity sensor has included
one incorrect value that is not supported by the HW.
This value is now corrected from 25Hz to 20Hz. The
corresponding rate in the time table is corrected to
50ms accordingly.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 526cdb6..ef1ab49 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -177,10 +177,10 @@ static const char reg_vleds[] = "Vleds";
/*
* Supported stand alone rates in ms from chip data sheet
- * {10, 20, 30, 40, 70, 100, 200, 500, 1000, 2000};
+ * {10, 20, 30, 50, 70, 100, 200, 500, 1000, 2000};
*/
-static const s16 prox_rates_hz[] = {100, 50, 33, 25, 14, 10, 5, 2};
-static const s16 prox_rates_ms[] = {10, 20, 30, 40, 70, 100, 200, 500};
+static const s16 prox_rates_hz[] = {100, 50, 33, 20, 14, 10, 5, 2};
+static const s16 prox_rates_ms[] = {10, 20, 30, 50, 70, 100, 200, 500};
/* Supported IR-led currents in mA */
static const u8 prox_curr_ma[] = {5, 10, 20, 50, 100, 150, 200};
--
1.7.10.4
From: Onur Atilla <[email protected]>
"lux0_raw" file gives the raw Ambient Light Sensor (ALS) value,
before adjusting it with the calibration coefficients, whereas
"lux0_input"returns the calibrated ALS value.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 82c30e7..d8d6526 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -395,6 +395,12 @@ static int bh1770_lux_read_result(struct bh1770_chip *chip)
return bh1770_lux_raw_to_adjusted(chip, chip->lux_data_raw);
}
+static int bh1770_lux_read_raw_result(struct bh1770_chip *chip)
+{
+ bh1770_lux_get_result(chip);
+ return chip->lux_data_raw;
+}
+
/*
* Chip on / off functions are called while keeping mutex except probe
* or remove phase
@@ -725,6 +731,29 @@ static ssize_t bh1770_lux_result_show(struct device *dev,
return ret;
}
+static ssize_t bh1770_lux_raw_result_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bh1770_chip *chip = dev_get_drvdata(dev);
+ ssize_t ret;
+ long timeout;
+
+ if (pm_runtime_suspended(dev))
+ return -EIO; /* Chip is not enabled at all */
+
+ timeout = wait_event_interruptible_timeout(chip->wait,
+ !chip->lux_wait_result,
+ msecs_to_jiffies(BH1770_TIMEOUT));
+ if (!timeout)
+ return -EIO;
+
+ mutex_lock(&chip->mutex);
+ ret = sprintf(buf, "%d\n", bh1770_lux_read_raw_result(chip));
+ mutex_unlock(&chip->mutex);
+
+ return ret;
+}
+
static ssize_t bh1770_lux_range_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1184,6 +1213,7 @@ static DEVICE_ATTR(lux0_glass_factor, S_IRUGO, bh1770_lux_glass_factor_show,
NULL);
static DEVICE_ATTR(lux0_sensor_comp_factor, S_IRUGO, bh1770_lux_scf_show, NULL);
static DEVICE_ATTR(lux0_input, S_IRUGO, bh1770_lux_result_show, NULL);
+static DEVICE_ATTR(lux0_raw, S_IRUGO, bh1770_lux_raw_result_show, NULL);
static DEVICE_ATTR(lux0_sensor_range, S_IRUGO, bh1770_lux_range_show, NULL);
static DEVICE_ATTR(lux0_rate, S_IRUGO | S_IWUSR, bh1770_get_lux_rate,
bh1770_set_lux_rate);
@@ -1205,6 +1235,7 @@ static struct attribute *sysfs_attrs[] = {
&dev_attr_lux0_glass_factor.attr,
&dev_attr_lux0_sensor_comp_factor.attr,
&dev_attr_lux0_input.attr,
+ &dev_attr_lux0_raw.attr,
&dev_attr_lux0_sensor_range.attr,
&dev_attr_lux0_rate.attr,
&dev_attr_lux0_rate_avail.attr,
--
1.7.10.4
the prox0_raw file in the sysfs interface reads the proximity
value directly from the register instead of reporting the last
read value; in this way userspace applications can have a real
time value
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index ac6d0c8..031a9fa 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -786,6 +786,11 @@ static ssize_t bh1770_prox_result_show(struct device *dev,
ssize_t ret;
mutex_lock(&chip->mutex);
+ /*
+ * if this function fails the prox_data will store
+ * the value from the previous read
+ */
+ bh1770_ps_get_result(chip);
if (chip->prox_enable_count && !pm_runtime_suspended(dev))
ret = sprintf(buf, "%d\n", chip->prox_data);
else
--
1.7.10.4
prox_read_result() has been split in two functions:
- ps_get_result(): reads the proximity value from the register
- prox_read_result(): applies the logic above the proximity value
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 53 +++++++++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 05769e3..ac6d0c8 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -253,13 +253,6 @@ static inline int bh1770_led_cfg(struct bh1770_chip *chip)
chip->prox_led);
}
-
-/*
- * Following two functions converts raw lux values from HW to normalized
- * values. Purpose is to compensate differences between different sensor
- * versions and variants so that result means about the same between
- * versions. Chip->mutex is kept when this is called.
- */
static int bh1770_prox_set_threshold(struct bh1770_chip *chip)
{
/* sysfs may call this when the chip is powered off */
@@ -270,6 +263,12 @@ static int bh1770_prox_set_threshold(struct bh1770_chip *chip)
chip->prox_threshold);
}
+/*
+ * Following two functions converts raw lux values from HW to normalized
+ * values. Purpose is to compensate differences between different sensor
+ * versions and variants so that result means about the same between
+ * versions. Chip->mutex is kept when this is called.
+ */
static inline u16 bh1770_lux_raw_to_adjusted(struct bh1770_chip *chip, u16 raw)
{
u32 lux;
@@ -343,6 +342,30 @@ static int bh1770_lux_get_result(struct bh1770_chip *chip)
return 0;
}
+static int bh1770_ps_get_result(struct bh1770_chip *chip)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(chip->client, BH1770_PS_DATA_LED1);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * when ALS levels goes above limit, proximity result may be
+ * false proximity. Thus ignore the result. With real proximity
+ * there is a shadow causing low als levels.
+ */
+ if (chip->lux_data_raw > PROX_IGNORE_LUX_LIMIT)
+ return 0;
+
+ if (ret > BH1770_PROX_RANGE)
+ chip->prox_data = BH1770_PROX_RANGE;
+ else
+ chip->prox_data = ret;
+
+ return 0;
+}
+
/* Calculate correction value which contains chip and device specific parts */
static u32 bh1770_get_corr_value(struct bh1770_chip *chip)
{
@@ -450,23 +473,15 @@ static int bh1770_prox_read_result(struct bh1770_chip *chip)
bool above;
u8 mode;
- ret = i2c_smbus_read_byte_data(chip->client, BH1770_PS_DATA_LED1);
+ ret = bh1770_ps_get_result(chip);
if (ret < 0)
- goto out;
+ return ret;
- if (ret > chip->prox_threshold)
+ if (chip->prox_data > chip->prox_threshold)
above = true;
else
above = false;
- /*
- * when ALS levels goes above limit, proximity result may be
- * false proximity. Thus ignore the result. With real proximity
- * there is a shadow causing low als levels.
- */
- if (chip->lux_data_raw > PROX_IGNORE_LUX_LIMIT)
- ret = 0;
-
/* Strong proximity level or force mode requires immediate response */
if (chip->prox_data >= chip->prox_abs_thres ||
chip->prox_force_update)
@@ -495,7 +510,7 @@ static int bh1770_prox_read_result(struct bh1770_chip *chip)
bh1770_report_input_value(chip, mode);
sysfs_notify(&chip->client->dev.kobj, NULL, "prox0_raw");
}
-out:
+
return ret;
}
--
1.7.10.4
From: Onur Atilla <[email protected]>
The Ambient Light Sensor (ALS) glass attenuation parameter should
be configurable and two new parameters are introduced:
als_scf_BH1770 and als_scf_SFH7770.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
include/linux/i2c/bh1770glc.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/i2c/bh1770glc.h b/include/linux/i2c/bh1770glc.h
index 8b5e2df..a08060a 100644
--- a/include/linux/i2c/bh1770glc.h
+++ b/include/linux/i2c/bh1770glc.h
@@ -47,6 +47,8 @@ struct bh1770_platform_data {
__u8 led_def_curr;
#define BH1770_NEUTRAL_GA 16384 /* 16384 / 16384 = 1 */
__u32 glass_attenuation;
+ __u32 als_scf_BH1770;
+ __u32 als_scf_SFH7770;
int (*setup_resources)(void);
int (*release_resources)(void);
};
--
1.7.10.4
From: Onur Atilla <[email protected]>
Removed unused variables and definitions, adjusted some code
alignement and removed trailing spaces.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 55 +++++++++++++++++++----------------------
include/linux/i2c/bh1770glc.h | 25 ++++++++++---------
2 files changed, 38 insertions(+), 42 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index fe49964..054d3f3 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -105,27 +105,25 @@
#define BH1770_ENABLE 1
#define BH1770_PROX_CHANNELS 1
-#define BH1770_LUX_DEFAULT_RATE 1 /* Index to lux rate table */
-#define BH1770_PROX_DEFAULT_RATE 1 /* Direct HW value =~ 50Hz */
-#define BH1770_PROX_DEF_RATE_THRESH 6 /* Direct HW value =~ 5 Hz */
-#define BH1770_STARTUP_DELAY 50
-#define BH1770_RESET_TIME 10
-#define BH1770_TIMEOUT 2100 /* Timeout in 2.1 seconds */
-
-#define BH1770_LUX_RANGE 65535
-#define BH1770_PROX_RANGE 255
-#define BH1770_COEF_SCALER 1024
-#define BH1770_CALIB_SCALER 8192
-#define BH1770_LUX_NEUTRAL_CALIB_VALUE (1 * BH1770_CALIB_SCALER)
-#define BH1770_LUX_DEF_THRES 1000
-#define BH1770_PROX_DEF_THRES 70
-#define BH1770_PROX_DEF_ABS_THRES 100
-#define BH1770_DEFAULT_PERSISTENCE 10
-#define BH1770_PROX_MAX_PERSISTENCE 50
#define BH1770_LUX_GA_SCALE 16384
#define BH1770_LUX_CF_SCALE 2048 /* CF ChipFactor */
-#define BH1770_NEUTRAL_CF BH1770_LUX_CF_SCALE
-#define BH1770_LUX_CORR_SCALE 4096
+#define BH1770_LUX_DEFAULT_RATE 1 /* Index to lux rate table */
+#define BH1770_PROX_DEFAULT_RATE 1 /* Direct HW value =~ 50Hz */
+#define BH1770_PROX_DEF_RATE_THRESH 6 /* Direct HW value =~ 5 Hz */
+#define BH1770_STARTUP_DELAY 50
+#define BH1770_RESET_TIME 10
+#define BH1770_TIMEOUT 2100 /* Timeout in 2.1 seconds */
+
+#define BH1770_LUX_RANGE 65535
+#define BH1770_PROX_RANGE 255
+#define BH1770_CALIB_SCALER 8192
+#define BH1770_LUX_NEUTRAL_CALIB_VALUE (1 * BH1770_CALIB_SCALER)
+#define BH1770_LUX_DEF_THRES 1000
+#define BH1770_PROX_DEF_THRES 100
+#define BH1770_DEFAULT_PERSISTENCE 10
+#define BH1770_PROX_MAX_PERSISTENCE 50
+#define BH1770_NEUTRAL_CF BH1770_LUX_CF_SCALE
+#define BH1770_LUX_CORR_SCALE 4096
#define PROX_ABOVE_THRESHOLD 1
#define PROX_BELOW_THRESHOLD 0
@@ -158,7 +156,6 @@ struct bh1770_chip {
int prox_enable_count;
u16 prox_coef;
- u16 prox_const;
int prox_rate;
int prox_rate_threshold;
u8 prox_persistence;
@@ -356,7 +353,7 @@ static int bh1770_ps_get_result(struct bh1770_chip *chip)
* when ALS levels goes above limit, proximity result may be
* false proximity. Thus ignore the result. With real proximity
* there is a shadow causing low als levels.
- */
+ */
if (chip->lux_data_raw > PROX_IGNORE_LUX_LIMIT)
return 0;
@@ -547,8 +544,6 @@ static int bh1770_detect(struct bh1770_chip *chip)
part = (u8)ret;
chip->revision = (part & BH1770_REV_MASK) >> BH1770_REV_SHIFT;
- chip->prox_coef = BH1770_COEF_SCALER;
- chip->prox_const = 0;
chip->lux_cf = BH1770_NEUTRAL_CF;
chip->prox_min_threshold = BH1770_PROX_DEF_THRES;
@@ -816,7 +811,7 @@ static ssize_t bh1770_prox_enable_show(struct device *dev,
static ssize_t bh1770_prox_result_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
+ struct bh1770_chip *chip = dev_get_drvdata(dev);
ssize_t ret;
mutex_lock(&chip->mutex);
@@ -1218,7 +1213,6 @@ static DEVICE_ATTR(chip_id, S_IRUGO, bh1770_chip_id_show, NULL);
static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, bh1770_power_state_show,
bh1770_power_state_store);
-
static struct attribute *sysfs_attrs[] = {
&dev_attr_lux0_calibscale.attr,
&dev_attr_lux0_calibscale_default.attr,
@@ -1282,11 +1276,6 @@ static int bh1770_probe(struct i2c_client *client,
else
chip->lux_ga = chip->pdata->glass_attenuation;
- chip->prox_led = chip->pdata->led_def_curr;
- chip->prox_persistence = BH1770_DEFAULT_PERSISTENCE;
- chip->prox_rate_threshold = BH1770_PROX_DEF_RATE_THRESH;
- chip->prox_rate = BH1770_PROX_DEFAULT_RATE;
- chip->prox_data = 0;
/* Make sure that the given hysteresis value is in range */
if ((chip->pdata->prox_hysteresis > BH1770_PROX_RANGE) ||
(chip->pdata->prox_hysteresis < 0)) {
@@ -1295,6 +1284,12 @@ static int bh1770_probe(struct i2c_client *client,
chip->prox_hysteresis = chip->pdata->prox_hysteresis;
}
+ chip->prox_led = chip->pdata->led_def_curr;
+ chip->prox_persistence = BH1770_DEFAULT_PERSISTENCE;
+ chip->prox_rate_threshold = BH1770_PROX_DEF_RATE_THRESH;
+ chip->prox_rate = BH1770_PROX_DEFAULT_RATE;
+ chip->prox_data = 0;
+
chip->regs[0].supply = reg_vcc;
chip->regs[1].supply = reg_vleds;
diff --git a/include/linux/i2c/bh1770glc.h b/include/linux/i2c/bh1770glc.h
index ed670dd..3efbae4 100644
--- a/include/linux/i2c/bh1770glc.h
+++ b/include/linux/i2c/bh1770glc.h
@@ -25,6 +25,15 @@
#ifndef __BH1770_H__
#define __BH1770_H__
+#define BH1770_LED_5mA 0
+#define BH1770_LED_10mA 1
+#define BH1770_LED_20mA 2
+#define BH1770_LED_50mA 3
+#define BH1770_LED_100mA 4
+#define BH1770_LED_150mA 5
+#define BH1770_LED_200mA 6
+#define BH1770_NEUTRAL_GA 16384 /* 16384 / 16384 = 1 */
+
/**
* struct bh1770_platform_data - platform data for bh1770glc driver
* @led_def_curr: IR led driving current.
@@ -37,18 +46,10 @@
*/
struct bh1770_platform_data {
-#define BH1770_LED_5mA 0
-#define BH1770_LED_10mA 1
-#define BH1770_LED_20mA 2
-#define BH1770_LED_50mA 3
-#define BH1770_LED_100mA 4
-#define BH1770_LED_150mA 5
-#define BH1770_LED_200mA 6
- __u8 led_def_curr;
-#define BH1770_NEUTRAL_GA 16384 /* 16384 / 16384 = 1 */
- __u32 glass_attenuation;
- __u32 als_scf_BH1770;
- __u32 als_scf_SFH7770;
+ u8 led_def_curr;
+ u32 glass_attenuation;
+ u32 als_scf_BH1770;
+ u32 als_scf_SFH7770;
u8 prox_hysteresis;
u8 prox_min_thresh_BH1770;
u8 prox_min_thresh_SFH7770;
--
1.7.10.4
From: Onur Atilla <[email protected]>
The als_int_enable switch decides whether the sensor interrupt
signal is triggered by both proximity and the ambient light
sensors or only by the proximity sensor.
The low and high threshold values are set to their minimum and
maximum in order to disable ALS interrupt.
If als_int_enable is set to 0, then the INT output signal of the
sensor will not be used by the ALS, but only by the proximity
sensor.
The interrupt setting can be changed during runtime by defining
new threshold values for the ambient light sensor.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 10 ++++++++++
include/linux/i2c/bh1770glc.h | 1 +
2 files changed, 11 insertions(+)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 383cefe..526cdb6 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -1280,6 +1280,16 @@ static int bh1770_probe(struct i2c_client *client,
chip->lux_threshold_lo = BH1770_LUX_DEF_THRES;
chip->lux_threshold_hi = BH1770_LUX_DEF_THRES;
+ /* Modify the ALS threshold values
+ * only if ALS interrupt is disabled by the platform data.
+ * Setting the low threshold and the high threshold to the
+ * lowest and highest values, respectively, disables the IRQ for ALS.
+ */
+ if (chip->pdata->als_int_enable == 0) {
+ chip->lux_threshold_lo = 0;
+ chip->lux_threshold_hi = BH1770_LUX_RANGE;
+ }
+
if (chip->pdata->glass_attenuation == 0)
chip->lux_ga = BH1770_NEUTRAL_GA;
else
diff --git a/include/linux/i2c/bh1770glc.h b/include/linux/i2c/bh1770glc.h
index aaf0906..6fb4488 100644
--- a/include/linux/i2c/bh1770glc.h
+++ b/include/linux/i2c/bh1770glc.h
@@ -53,6 +53,7 @@ struct bh1770_platform_data {
u8 prox_hysteresis;
u8 prox_min_thresh_BH1770;
u8 prox_min_thresh_SFH7770;
+ u8 als_int_enable;
int (*setup_resources)(void);
int (*release_resources)(void);
};
--
1.7.10.4
lux_raw_result_show() will run directly the lux_get_result()
instead of using another support function
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index b5fc2b9..eec799e 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -385,12 +385,6 @@ static int bh1770_lux_read_result(struct bh1770_chip *chip)
return bh1770_lux_raw_to_adjusted(chip, chip->lux_data_raw);
}
-static int bh1770_lux_read_raw_result(struct bh1770_chip *chip)
-{
- bh1770_lux_get_result(chip);
- return chip->lux_data_raw;
-}
-
/*
* Chip on / off functions are called while keeping mutex except probe
* or remove phase
@@ -725,7 +719,8 @@ static ssize_t bh1770_lux_raw_result_show(struct device *dev,
return -EIO;
mutex_lock(&chip->mutex);
- ret = sprintf(buf, "%d\n", bh1770_lux_read_raw_result(chip));
+ bh1770_lux_get_result(chip);
+ ret = sprintf(buf, "%d\n", chip->lux_data_raw);
mutex_unlock(&chip->mutex);
return ret;
--
1.7.10.4
From: Onur Atilla <[email protected]>
Changed the neutral glass attenuation value from 16384
to 8192. This is for adaptation to the new scaling factor.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
include/linux/i2c/bh1770glc.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/i2c/bh1770glc.h b/include/linux/i2c/bh1770glc.h
index 3efbae4..aaf0906 100644
--- a/include/linux/i2c/bh1770glc.h
+++ b/include/linux/i2c/bh1770glc.h
@@ -32,7 +32,7 @@
#define BH1770_LED_100mA 4
#define BH1770_LED_150mA 5
#define BH1770_LED_200mA 6
-#define BH1770_NEUTRAL_GA 16384 /* 16384 / 16384 = 1 */
+#define BH1770_NEUTRAL_GA 8192 /* 8192 / 8192 = 1 */
/**
* struct bh1770_platform_data - platform data for bh1770glc driver
@@ -41,7 +41,7 @@
* @setup_resources: Call back for interrupt line setup function
* @release_resources: Call back for interrupte line release function
*
- * Example of glass attenuation: 16384 * 385 / 100 means attenuation factor
+ * Example of glass attenuation: 8192 * 385 / 100 means attenuation factor
* of 3.85. i.e. light_above_sensor = light_above_cover_window / 3.85
*/
--
1.7.10.4
From: Onur Atilla <[email protected]>
Introduced lux0_glass_factor and lux0_comp_factor on sysfs
lux0_glass_factor and lux0_sensor_comp_factor are provided as
read-only files on the sysfs structure of the bh1770glc optical sensor.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index d60b317..82c30e7 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -467,6 +467,7 @@ static int bh1770_prox_mode_control(struct bh1770_chip *chip)
static void bh1770_report_input_value(struct bh1770_chip *chip, int val)
{
input_report_switch(chip->input_dev, SW_FRONT_PROXIMITY, val);
+ input_sync(chip->input_dev);
}
/* chip->mutex is kept when this is called */
@@ -551,6 +552,7 @@ static int bh1770_detect(struct bh1770_chip *chip)
if ((manu == BH1770_MANUFACT_ROHM) &&
((part & BH1770_PART_MASK) == BH1770_PART)) {
snprintf(chip->chipname, sizeof(chip->chipname), "BH1770GLC");
+ chip->lux_cf = chip->pdata->als_scf_BH1770;
return 0;
}
@@ -560,6 +562,7 @@ static int bh1770_detect(struct bh1770_chip *chip)
/* Values selected by comparing different versions */
chip->prox_coef = 819; /* 0.8 * BH1770_COEF_SCALER */
chip->prox_const = 40;
+ chip->lux_cf = chip->pdata->als_scf_SFH7770;
return 0;
}
@@ -1030,6 +1033,20 @@ static ssize_t bh1770_lux_calib_store(struct device *dev,
return len;
}
+static ssize_t bh1770_lux_glass_factor_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bh1770_chip *chip = dev_get_drvdata(dev);
+ return sprintf(buf, "%u\n", chip->lux_ga);
+}
+
+static ssize_t bh1770_lux_scf_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bh1770_chip *chip = dev_get_drvdata(dev);
+ return sprintf(buf, "%u\n", chip->lux_cf);
+}
+
static ssize_t bh1770_get_lux_rate_avail(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1163,6 +1180,9 @@ static DEVICE_ATTR(lux0_calibscale, S_IRUGO | S_IWUSR, bh1770_lux_calib_show,
static DEVICE_ATTR(lux0_calibscale_default, S_IRUGO,
bh1770_lux_calib_default_show,
NULL);
+static DEVICE_ATTR(lux0_glass_factor, S_IRUGO, bh1770_lux_glass_factor_show,
+ NULL);
+static DEVICE_ATTR(lux0_sensor_comp_factor, S_IRUGO, bh1770_lux_scf_show, NULL);
static DEVICE_ATTR(lux0_input, S_IRUGO, bh1770_lux_result_show, NULL);
static DEVICE_ATTR(lux0_sensor_range, S_IRUGO, bh1770_lux_range_show, NULL);
static DEVICE_ATTR(lux0_rate, S_IRUGO | S_IWUSR, bh1770_get_lux_rate,
@@ -1182,6 +1202,8 @@ static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, bh1770_power_state_show,
static struct attribute *sysfs_attrs[] = {
&dev_attr_lux0_calibscale.attr,
&dev_attr_lux0_calibscale_default.attr,
+ &dev_attr_lux0_glass_factor.attr,
+ &dev_attr_lux0_sensor_comp_factor.attr,
&dev_attr_lux0_input.attr,
&dev_attr_lux0_sensor_range.attr,
&dev_attr_lux0_rate.attr,
--
1.7.10.4
From: Onur Atilla <[email protected]>
Sensor compensation factor input from the platform
is being checked now before use.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index cb63c25..383cefe 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -123,6 +123,7 @@
#define BH1770_LUX_GA_SCALE 8192
#define BH1770_LUX_CF_SCALE 8192 /* CF ChipFactor */
#define BH1770_NEUTRAL_CF BH1770_LUX_CF_SCALE
+#define BH1770_LUX_MAX_CF (10 * BH1770_NEUTRAL_CF)
#define BH1770_LUX_CORR_SCALE 4096
#define PROX_ABOVE_THRESHOLD 1
@@ -550,7 +551,11 @@ static int bh1770_detect(struct bh1770_chip *chip)
if ((manu == BH1770_MANUFACT_ROHM) &&
((part & BH1770_PART_MASK) == BH1770_PART)) {
snprintf(chip->chipname, sizeof(chip->chipname), "BH1770GLC");
- chip->lux_cf = chip->pdata->als_scf_BH1770;
+
+ /* apply sensor compensation factor only after verifying it */
+ if ((chip->pdata->als_scf_BH1770 > 0) &&
+ (chip->pdata->als_scf_BH1770 < BH1770_LUX_MAX_CF))
+ chip->lux_cf = chip->pdata->als_scf_BH1770;
/* apply minimum threshold value only after verifying it */
if ((chip->pdata->prox_min_thresh_BH1770 > 0) &&
@@ -565,7 +570,11 @@ static int bh1770_detect(struct bh1770_chip *chip)
if ((manu == BH1770_MANUFACT_OSRAM) &&
((part & BH1770_PART_MASK) == BH1770_PART)) {
snprintf(chip->chipname, sizeof(chip->chipname), "SFH7770");
- chip->lux_cf = chip->pdata->als_scf_SFH7770;
+
+ /* apply sensor compensation factor only after verifying it */
+ if ((chip->pdata->als_scf_SFH7770 > 0) &&
+ (chip->pdata->als_scf_SFH7770 < BH1770_LUX_MAX_CF))
+ chip->lux_cf = chip->pdata->als_scf_SFH7770;
/* apply minimum threshold value only after verifying it */
if ((chip->pdata->prox_min_thresh_SFH7770 > 0) &&
--
1.7.10.4
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 031a9fa..bd90eaf 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -273,7 +273,7 @@ static inline u16 bh1770_lux_raw_to_adjusted(struct bh1770_chip *chip, u16 raw)
{
u32 lux;
lux = ((u32)raw * chip->lux_corr) / BH1770_LUX_CORR_SCALE;
- return min(lux, (u32)BH1770_LUX_RANGE);
+ return min_t(u32, lux, BH1770_LUX_RANGE);
}
static inline u16 bh1770_lux_adjusted_to_raw(struct bh1770_chip *chip,
--
1.7.10.4
proximity sensor doesn't need to be adjusted; removed all the
overcode used for the proximity coefficients
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 39 ++-------------------------------------
1 file changed, 2 insertions(+), 37 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 53f3c17..05769e3 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -165,7 +165,6 @@ struct bh1770_chip {
u8 prox_persistence_counter;
u8 prox_data;
u8 prox_threshold;
- u8 prox_threshold_hw;
bool prox_force_update;
u8 prox_abs_thres;
u8 prox_led;
@@ -254,33 +253,6 @@ static inline int bh1770_led_cfg(struct bh1770_chip *chip)
chip->prox_led);
}
-/*
- * Following two functions converts raw ps values from HW to normalized
- * values. Purpose is to compensate differences between different sensor
- * versions and variants so that result means about the same between
- * versions.
- */
-static inline u8 bh1770_psraw_to_adjusted(struct bh1770_chip *chip, u8 psraw)
-{
- u16 adjusted;
- adjusted = (u16)(((u32)(psraw + chip->prox_const) * chip->prox_coef) /
- BH1770_COEF_SCALER);
- if (adjusted > BH1770_PROX_RANGE)
- adjusted = BH1770_PROX_RANGE;
- return adjusted;
-}
-
-static inline u8 bh1770_psadjusted_to_raw(struct bh1770_chip *chip, u8 ps)
-{
- u16 raw;
-
- raw = (((u32)ps * BH1770_COEF_SCALER) / chip->prox_coef);
- if (raw > chip->prox_const)
- raw = raw - chip->prox_const;
- else
- raw = 0;
- return raw;
-}
/*
* Following two functions converts raw lux values from HW to normalized
@@ -290,17 +262,12 @@ static inline u8 bh1770_psadjusted_to_raw(struct bh1770_chip *chip, u8 ps)
*/
static int bh1770_prox_set_threshold(struct bh1770_chip *chip)
{
- u8 tmp = 0;
-
/* sysfs may call this when the chip is powered off */
if (pm_runtime_suspended(&chip->client->dev))
return 0;
- tmp = bh1770_psadjusted_to_raw(chip, chip->prox_threshold);
- chip->prox_threshold_hw = tmp;
-
return i2c_smbus_write_byte_data(chip->client, BH1770_PS_TH_LED1,
- tmp);
+ chip->prox_threshold);
}
static inline u16 bh1770_lux_raw_to_adjusted(struct bh1770_chip *chip, u16 raw)
@@ -487,7 +454,7 @@ static int bh1770_prox_read_result(struct bh1770_chip *chip)
if (ret < 0)
goto out;
- if (ret > chip->prox_threshold_hw)
+ if (ret > chip->prox_threshold)
above = true;
else
above = false;
@@ -500,8 +467,6 @@ static int bh1770_prox_read_result(struct bh1770_chip *chip)
if (chip->lux_data_raw > PROX_IGNORE_LUX_LIMIT)
ret = 0;
- chip->prox_data = bh1770_psraw_to_adjusted(chip, ret);
-
/* Strong proximity level or force mode requires immediate response */
if (chip->prox_data >= chip->prox_abs_thres ||
chip->prox_force_update)
--
1.7.10.4
The driver generates an event in /dev/input/ under the name
'bh1770'. It's a switch event where is reported '0' or '1'
whenever the sensor detects something crossing the threshold.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Phil Carmody <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index f4975f7..d60b317 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/slab.h>
+#include <linux/input.h>
#define BH1770_ALS_CONTROL 0x80 /* ALS operation mode control */
#define BH1770_PS_CONTROL 0x81 /* PS operation mode control */
@@ -168,6 +169,8 @@ struct bh1770_chip {
bool prox_force_update;
u8 prox_abs_thres;
u8 prox_led;
+
+ struct input_dev *input_dev;
};
static const char reg_vcc[] = "Vcc";
@@ -461,6 +464,11 @@ static int bh1770_prox_mode_control(struct bh1770_chip *chip)
return 0;
}
+static void bh1770_report_input_value(struct bh1770_chip *chip, int val)
+{
+ input_report_switch(chip->input_dev, SW_FRONT_PROXIMITY, val);
+}
+
/* chip->mutex is kept when this is called */
static int bh1770_prox_read_result(struct bh1770_chip *chip)
{
@@ -506,13 +514,13 @@ static int bh1770_prox_read_result(struct bh1770_chip *chip)
} else {
chip->prox_persistence_counter = 0;
mode = PROX_BELOW_THRESHOLD;
- chip->prox_data = 0;
ret = 0;
}
/* Set proximity detection rate based on above or below value */
if (ret == 0) {
bh1770_prox_rate(chip, mode);
+ bh1770_report_input_value(chip, mode);
sysfs_notify(&chip->client->dev.kobj, NULL, "prox0_raw");
}
out:
@@ -818,6 +826,42 @@ static int bh1770_prox_rate_validate(int rate)
return i;
}
+static void bh1770_input_cleanup(struct bh1770_chip *chip)
+{
+ input_unregister_device(chip->input_dev);
+}
+
+static int bh1770_input_init(struct bh1770_chip *chip)
+{
+ int err;
+
+ chip->input_dev = input_allocate_device();
+ if (!chip->input_dev) {
+ err = -ENOMEM;
+ goto alloc_err;
+ }
+
+ chip->input_dev->id.bustype = BUS_I2C;
+ chip->input_dev->dev.parent = &chip->client->dev;
+ chip->input_dev->name = "bh1770glc";
+
+ input_set_drvdata(chip->input_dev, chip);
+
+ set_bit(EV_SW, chip->input_dev->evbit);
+ set_bit(SW_FRONT_PROXIMITY, chip->input_dev->swbit);
+
+ err = input_register_device(chip->input_dev);
+ if (err)
+ goto reg_err;
+
+ return 0;
+
+reg_err:
+ input_free_device(chip->input_dev);
+alloc_err:
+ return err;
+}
+
static ssize_t bh1770_set_prox_rate_above(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1246,6 +1290,13 @@ static int bh1770_probe(struct i2c_client *client,
}
}
+ err = bh1770_input_init(chip);
+ if (err < 0) {
+ dev_err(&client->dev,
+ "impossible to allocate input event device\n");
+ goto no_input_dev;
+ }
+
err = sysfs_create_group(&chip->client->dev.kobj,
&bh1770_attribute_group);
if (err < 0) {
@@ -1274,6 +1325,8 @@ fail5:
sysfs_remove_group(&chip->client->dev.kobj,
&bh1770_attribute_group);
fail4:
+ bh1770_input_cleanup(chip);
+no_input_dev:
if (chip->pdata->release_resources)
chip->pdata->release_resources();
fail3:
@@ -1294,6 +1347,9 @@ static int bh1770_remove(struct i2c_client *client)
sysfs_remove_group(&chip->client->dev.kobj,
&bh1770_attribute_group);
+ /* input interface cleanup */
+ bh1770_input_cleanup(chip);
+
if (chip->pdata->release_resources)
chip->pdata->release_resources();
--
1.7.10.4
From: Onur Atilla <[email protected]>
Some obsolete version-dependent coefficient and constant settings
were removed out of the sensor detection functions. These values
cause unwanted offset between different sensor types.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index d8d6526..53f3c17 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -565,9 +565,6 @@ static int bh1770_detect(struct bh1770_chip *chip)
if ((manu == BH1770_MANUFACT_OSRAM) &&
((part & BH1770_PART_MASK) == BH1770_PART)) {
snprintf(chip->chipname, sizeof(chip->chipname), "SFH7770");
- /* Values selected by comparing different versions */
- chip->prox_coef = 819; /* 0.8 * BH1770_COEF_SCALER */
- chip->prox_const = 40;
chip->lux_cf = chip->pdata->als_scf_SFH7770;
return 0;
}
--
1.7.10.4
From: Onur Atilla <[email protected]>
Added dynamic threshold capability to the driver and removed
constant threshold value setting, thresh_above1_value, from
the sysfs interface.
Only one threshold value is visible and configurable through
the sysfs interface now; it is prox0_threshold_value. According
to the actual status of the proximity interrupt, the threshold
is set dynamically using a newly introduced hysteresis value.
Hysteresis is a configurable parameter.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 96 +++++++++++++++++++++++++----------------
include/linux/i2c/bh1770glc.h | 3 ++
2 files changed, 61 insertions(+), 38 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index eec799e..fe49964 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -165,8 +165,10 @@ struct bh1770_chip {
u8 prox_persistence_counter;
u8 prox_data;
u8 prox_threshold;
+ u8 prox_calib_threshold;
+ u8 prox_min_threshold;
+ u8 prox_hysteresis;
bool prox_force_update;
- u8 prox_abs_thres;
u8 prox_led;
struct input_dev *input_dev;
@@ -476,25 +478,45 @@ static int bh1770_prox_read_result(struct bh1770_chip *chip)
else
above = false;
- /* Strong proximity level or force mode requires immediate response */
- if (chip->prox_data >= chip->prox_abs_thres ||
- chip->prox_force_update)
+ /* Forced mode requires immediate response */
+ if (chip->prox_force_update)
chip->prox_persistence_counter = chip->prox_persistence;
chip->prox_force_update = false;
- /* Persistence filttering to reduce false proximity events */
+ /* Persistence filtering to reduce false proximity events */
if (likely(above)) {
if (chip->prox_persistence_counter < chip->prox_persistence) {
chip->prox_persistence_counter++;
ret = -ENODATA;
} else {
mode = PROX_ABOVE_THRESHOLD;
+
+ /*
+ * When above the threshold, reset the threshold value
+ * to a lower value defined by the given hysteresis
+ * The lowest value allowed is the min value
+ **/
+ if ((chip->prox_calib_threshold - chip->prox_hysteresis)
+ >= chip->prox_min_threshold) {
+ chip->prox_threshold =
+ chip->prox_calib_threshold -
+ chip->prox_hysteresis;
+ bh1770_prox_set_threshold(chip);
+ }
+ chip->prox_persistence_counter = 0;
ret = 0;
}
} else {
chip->prox_persistence_counter = 0;
mode = PROX_BELOW_THRESHOLD;
+
+ /*
+ * When below the threshold, reset the threshold value
+ * to the calibration value
+ */
+ chip->prox_threshold = chip->prox_calib_threshold;
+ bh1770_prox_set_threshold(chip);
ret = 0;
}
@@ -528,11 +550,20 @@ static int bh1770_detect(struct bh1770_chip *chip)
chip->prox_coef = BH1770_COEF_SCALER;
chip->prox_const = 0;
chip->lux_cf = BH1770_NEUTRAL_CF;
+ chip->prox_min_threshold = BH1770_PROX_DEF_THRES;
if ((manu == BH1770_MANUFACT_ROHM) &&
((part & BH1770_PART_MASK) == BH1770_PART)) {
snprintf(chip->chipname, sizeof(chip->chipname), "BH1770GLC");
chip->lux_cf = chip->pdata->als_scf_BH1770;
+
+ /* apply minimum threshold value only after verifying it */
+ if ((chip->pdata->prox_min_thresh_BH1770 > 0) &&
+ (chip->pdata->prox_min_thresh_BH1770 <
+ BH1770_PROX_RANGE)) {
+ chip->prox_min_threshold =
+ chip->pdata->prox_min_thresh_BH1770;
+ }
return 0;
}
@@ -540,6 +571,14 @@ static int bh1770_detect(struct bh1770_chip *chip)
((part & BH1770_PART_MASK) == BH1770_PART)) {
snprintf(chip->chipname, sizeof(chip->chipname), "SFH7770");
chip->lux_cf = chip->pdata->als_scf_SFH7770;
+
+ /* apply minimum threshold value only after verifying it */
+ if ((chip->pdata->prox_min_thresh_SFH7770 > 0) &&
+ (chip->pdata->prox_min_thresh_SFH7770 <
+ BH1770_PROX_RANGE)) {
+ chip->prox_min_threshold =
+ chip->pdata->prox_min_thresh_SFH7770;
+ }
return 0;
}
@@ -929,6 +968,8 @@ static ssize_t bh1770_set_prox_thres(struct device *dev,
mutex_unlock(&chip->mutex);
if (ret < 0)
return ret;
+ /* Remember the calibrated threshold value */
+ chip->prox_calib_threshold = chip->prox_threshold;
return count;
}
@@ -958,31 +999,6 @@ static ssize_t bh1770_prox_persistence_store(struct device *dev,
return len;
}
-static ssize_t bh1770_prox_abs_thres_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%u\n", chip->prox_abs_thres);
-}
-
-static ssize_t bh1770_prox_abs_thres_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (kstrtoul(buf, 0, &value))
- return -EINVAL;
-
- if (value > BH1770_PROX_RANGE)
- return -EINVAL;
-
- chip->prox_abs_thres = value;
-
- return len;
-}
-
static ssize_t bh1770_chip_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1162,10 +1178,7 @@ static ssize_t bh1770_set_lux_thresh_below(struct device *dev,
static DEVICE_ATTR(prox0_raw_en, S_IRUGO | S_IWUSR, bh1770_prox_enable_show,
bh1770_prox_enable_store);
-static DEVICE_ATTR(prox0_thresh_above1_value, S_IRUGO | S_IWUSR,
- bh1770_prox_abs_thres_show,
- bh1770_prox_abs_thres_store);
-static DEVICE_ATTR(prox0_thresh_above0_value, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(prox0_threshold_value, S_IRUGO | S_IWUSR,
bh1770_get_prox_thres,
bh1770_set_prox_thres);
static DEVICE_ATTR(prox0_raw, S_IRUGO, bh1770_prox_result_show, NULL);
@@ -1225,8 +1238,7 @@ static struct attribute *sysfs_attrs[] = {
&dev_attr_prox0_rate_above.attr,
&dev_attr_prox0_rate_below.attr,
&dev_attr_prox0_rate_avail.attr,
- &dev_attr_prox0_thresh_above0_value.attr,
- &dev_attr_prox0_thresh_above1_value.attr,
+ &dev_attr_prox0_threshold_value.attr,
&dev_attr_chip_id.attr,
&dev_attr_power_state.attr,
NULL
@@ -1270,13 +1282,18 @@ static int bh1770_probe(struct i2c_client *client,
else
chip->lux_ga = chip->pdata->glass_attenuation;
- chip->prox_threshold = BH1770_PROX_DEF_THRES;
chip->prox_led = chip->pdata->led_def_curr;
- chip->prox_abs_thres = BH1770_PROX_DEF_ABS_THRES;
chip->prox_persistence = BH1770_DEFAULT_PERSISTENCE;
chip->prox_rate_threshold = BH1770_PROX_DEF_RATE_THRESH;
chip->prox_rate = BH1770_PROX_DEFAULT_RATE;
chip->prox_data = 0;
+ /* Make sure that the given hysteresis value is in range */
+ if ((chip->pdata->prox_hysteresis > BH1770_PROX_RANGE) ||
+ (chip->pdata->prox_hysteresis < 0)) {
+ chip->prox_hysteresis = 0;
+ } else {
+ chip->prox_hysteresis = chip->pdata->prox_hysteresis;
+ }
chip->regs[0].supply = reg_vcc;
chip->regs[1].supply = reg_vleds;
@@ -1300,6 +1317,9 @@ static int bh1770_probe(struct i2c_client *client,
if (err < 0)
goto fail3;
+ chip->prox_threshold = chip->prox_min_threshold;
+ chip->prox_calib_threshold = chip->prox_threshold;
+
/* Start chip */
bh1770_chip_on(chip);
pm_runtime_set_active(&client->dev);
diff --git a/include/linux/i2c/bh1770glc.h b/include/linux/i2c/bh1770glc.h
index a08060a..ed670dd 100644
--- a/include/linux/i2c/bh1770glc.h
+++ b/include/linux/i2c/bh1770glc.h
@@ -49,6 +49,9 @@ struct bh1770_platform_data {
__u32 glass_attenuation;
__u32 als_scf_BH1770;
__u32 als_scf_SFH7770;
+ u8 prox_hysteresis;
+ u8 prox_min_thresh_BH1770;
+ u8 prox_min_thresh_SFH7770;
int (*setup_resources)(void);
int (*release_resources)(void);
};
--
1.7.10.4
kstrtoul() calls have been done by using base 0
up to now. This allowed hexadecimal and octal
entry on the sysfs interface.
Hexadecimal or octal entry is not required, nor
wanted for the proximity sensor.
The base is now changed to 10 in order to accept
only decimal numbers on the proximity sensor
sysfs interface.
Signed-off-by: Andi Shyti <[email protected]>
Signed-off-by: Onur Atilla <[email protected]>
---
drivers/misc/bh1770glc.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index bd90eaf..b5fc2b9 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -645,7 +645,7 @@ static ssize_t bh1770_power_state_store(struct device *dev,
unsigned long value;
ssize_t ret;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 10, &value))
return -EINVAL;
mutex_lock(&chip->mutex);
@@ -744,7 +744,7 @@ static ssize_t bh1770_prox_enable_store(struct device *dev,
struct bh1770_chip *chip = dev_get_drvdata(dev);
unsigned long value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 10, &value))
return -EINVAL;
mutex_lock(&chip->mutex);
@@ -883,7 +883,7 @@ static ssize_t bh1770_set_prox_rate_above(struct device *dev,
struct bh1770_chip *chip = dev_get_drvdata(dev);
unsigned long value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 10, &value))
return -EINVAL;
mutex_lock(&chip->mutex);
@@ -899,7 +899,7 @@ static ssize_t bh1770_set_prox_rate_below(struct device *dev,
struct bh1770_chip *chip = dev_get_drvdata(dev);
unsigned long value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 10, &value))
return -EINVAL;
mutex_lock(&chip->mutex);
@@ -923,7 +923,7 @@ static ssize_t bh1770_set_prox_thres(struct device *dev,
unsigned long value;
int ret;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 10, &value))
return -EINVAL;
if (value > BH1770_PROX_RANGE)
return -EINVAL;
@@ -952,7 +952,7 @@ static ssize_t bh1770_prox_persistence_store(struct device *dev,
struct bh1770_chip *chip = dev_get_drvdata(dev);
unsigned long value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 10, &value))
return -EINVAL;
if (value > BH1770_PROX_MAX_PERSISTENCE)
@@ -977,7 +977,7 @@ static ssize_t bh1770_prox_abs_thres_store(struct device *dev,
struct bh1770_chip *chip = dev_get_drvdata(dev);
unsigned long value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 0, &value))
return -EINVAL;
if (value > BH1770_PROX_RANGE)
@@ -1022,7 +1022,7 @@ static ssize_t bh1770_lux_calib_store(struct device *dev,
u32 old_calib;
u32 new_corr;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoul(buf, 10, &value))
return -EINVAL;
mutex_lock(&chip->mutex);
@@ -1084,7 +1084,7 @@ static ssize_t bh1770_set_lux_rate(struct device *dev,
unsigned long rate_hz;
int ret, i;
- if (strict_strtoul(buf, 0, &rate_hz))
+ if (kstrtoul(buf, 10, &rate_hz))
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(lux_rates_hz) - 1; i++)
@@ -1122,7 +1122,7 @@ static ssize_t bh1770_set_lux_thresh(struct bh1770_chip *chip, u16 *target,
int ret = 0;
unsigned long thresh;
- if (strict_strtoul(buf, 0, &thresh))
+ if (kstrtoul(buf, 10, &thresh))
return -EINVAL;
if (thresh > BH1770_LUX_RANGE)
--
1.7.10.4
From: Onur Atilla <[email protected]>
Instead of using a constant value, the LED current
of the proximity sensor is now made individually
configurable for each product.
bh1770glc reads the platform-defined data and sets
the most suitable current value accordingly.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 11 ++++++++++-
include/linux/i2c/bh1770glc.h | 1 +
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index ef1ab49..0af50bf 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -1256,6 +1256,7 @@ static int bh1770_probe(struct i2c_client *client,
{
struct bh1770_chip *chip;
int err;
+ u8 i;
chip = kzalloc(sizeof *chip, GFP_KERNEL);
if (!chip)
@@ -1274,7 +1275,15 @@ static int bh1770_probe(struct i2c_client *client,
goto fail1;
}
- chip->pdata = client->dev.platform_data;
+ /* Set the proximity sensor LED current according to the
+ * platform data. If the given value is out of range,
+ * use the closest supported current per default.
+ */
+ for (i = ARRAY_SIZE(prox_curr_ma)-1; i > 0; i--) {
+ if (chip->pdata->led1_def_curr_ma >= prox_curr_ma[i])
+ break;
+ }
+ chip->prox_led = i;
chip->lux_calib = BH1770_LUX_NEUTRAL_CALIB_VALUE;
chip->lux_rate_index = BH1770_LUX_DEFAULT_RATE;
chip->lux_threshold_lo = BH1770_LUX_DEF_THRES;
diff --git a/include/linux/i2c/bh1770glc.h b/include/linux/i2c/bh1770glc.h
index 6fb4488..9c081a8 100644
--- a/include/linux/i2c/bh1770glc.h
+++ b/include/linux/i2c/bh1770glc.h
@@ -47,6 +47,7 @@
struct bh1770_platform_data {
u8 led_def_curr;
+ u8 led1_def_curr_ma;
u32 glass_attenuation;
u32 als_scf_BH1770;
u32 als_scf_SFH7770;
--
1.7.10.4
From: Onur Atilla <[email protected]>
Changed all exposed scalers to 8192 (Q13) in order to
achieve consistency in the sysfs interface.
Signed-off-by: Onur Atilla <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
drivers/misc/bh1770glc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 054d3f3..cb63c25 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -105,8 +105,6 @@
#define BH1770_ENABLE 1
#define BH1770_PROX_CHANNELS 1
-#define BH1770_LUX_GA_SCALE 16384
-#define BH1770_LUX_CF_SCALE 2048 /* CF ChipFactor */
#define BH1770_LUX_DEFAULT_RATE 1 /* Index to lux rate table */
#define BH1770_PROX_DEFAULT_RATE 1 /* Direct HW value =~ 50Hz */
#define BH1770_PROX_DEF_RATE_THRESH 6 /* Direct HW value =~ 5 Hz */
@@ -122,6 +120,8 @@
#define BH1770_PROX_DEF_THRES 100
#define BH1770_DEFAULT_PERSISTENCE 10
#define BH1770_PROX_MAX_PERSISTENCE 50
+#define BH1770_LUX_GA_SCALE 8192
+#define BH1770_LUX_CF_SCALE 8192 /* CF ChipFactor */
#define BH1770_NEUTRAL_CF BH1770_LUX_CF_SCALE
#define BH1770_LUX_CORR_SCALE 4096
--
1.7.10.4
On Thu, Jun 13, 2013 at 08:20:37PM +0200, Andi Shyti wrote:
> From: Onur Atilla <[email protected]>
>
> Introduced lux0_glass_factor and lux0_comp_factor on sysfs
>
> lux0_glass_factor and lux0_sensor_comp_factor are provided as
> read-only files on the sysfs structure of the bh1770glc optical sensor.
You can't add/remove/modify sysfs files without the proper
Documentation/ABI changes as well. Please redo this patch with those
updates.
thanks,
greg k-h
On Thu, Jun 13, 2013 at 08:20:35PM +0200, Andi Shyti wrote:
> The driver generates an event in /dev/input/ under the name
> 'bh1770'. It's a switch event where is reported '0' or '1'
> whenever the sensor detects something crossing the threshold.
>
> Signed-off-by: Onur Atilla <[email protected]>
> Signed-off-by: Phil Carmody <[email protected]>
> Signed-off-by: Andi Shyti <[email protected]>
> ---
> drivers/misc/bh1770glc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 57 insertions(+), 1 deletion(-)
Doesn't this mean that this driver is now an "input" driver, so it
shouldn't be using the odd sysfs api, and should move to the
drivers/input/ directory tree?
thanks,
greg k-h
On Thu, Jun 13, 2013 at 08:20:34PM +0200, Andi Shyti wrote:
> Hi,
>
> This patchset contains a collection of new features and fixes for
> the bh1770glc driver for the BH1770 and SFH7770 proximity
> and ambient light sensor device.
Remind me again why this isn't an drivers/iio/ driver, using that api?
> In few words this is what it brings:
> - /dev/input/event interface
> - removal obsolete and wrong parameters
What do you mean by this? Userspace parameters? Did you just change
the user/kernel api? Or something else?
> - new relevant parameters for glass attenuation and glass
> factor, lux compensation due to the LED cover or ink
Again, why not iio?
thanks,
greg k-h
Hi Greg,
> > The driver generates an event in /dev/input/ under the name
> > 'bh1770'. It's a switch event where is reported '0' or '1'
> > whenever the sensor detects something crossing the threshold.
> >
> > Signed-off-by: Onur Atilla <[email protected]>
> > Signed-off-by: Phil Carmody <[email protected]>
> > Signed-off-by: Andi Shyti <[email protected]>
> > ---
> > drivers/misc/bh1770glc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 57 insertions(+), 1 deletion(-)
>
> Doesn't this mean that this driver is now an "input" driver, so it
> shouldn't be using the odd sysfs api, and should move to the
> drivers/input/ directory tree?
The driver has also lots of interfaces in
sysfs that are used from userspace, like proximity value and
ambient light value.
What the input interface provides is just one of the features
from the driver. Shall I move it anyway?
Andi
> > Introduced lux0_glass_factor and lux0_comp_factor on sysfs
> >
> > lux0_glass_factor and lux0_sensor_comp_factor are provided as
> > read-only files on the sysfs structure of the bh1770glc optical sensor.
>
> You can't add/remove/modify sysfs files without the proper
> Documentation/ABI changes as well. Please redo this patch with those
> updates.
Right! missed that, I'll resend it
Andi
On Tue, Jun 18, 2013 at 01:27:39AM +0200, Andi Shyti wrote:
> Hi Greg,
>
> > > The driver generates an event in /dev/input/ under the name
> > > 'bh1770'. It's a switch event where is reported '0' or '1'
> > > whenever the sensor detects something crossing the threshold.
> > >
> > > Signed-off-by: Onur Atilla <[email protected]>
> > > Signed-off-by: Phil Carmody <[email protected]>
> > > Signed-off-by: Andi Shyti <[email protected]>
> > > ---
> > > drivers/misc/bh1770glc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
> > > 1 file changed, 57 insertions(+), 1 deletion(-)
> >
> > Doesn't this mean that this driver is now an "input" driver, so it
> > shouldn't be using the odd sysfs api, and should move to the
> > drivers/input/ directory tree?
>
> The driver has also lots of interfaces in
> sysfs that are used from userspace, like proximity value and
> ambient light value.
>
> What the input interface provides is just one of the features
> from the driver. Shall I move it anyway?
Hm, why not make it an iio driver instead? That way you get input and
sysfs all together.
thanks,
greg k-h
> > This patchset contains a collection of new features and fixes for
> > the bh1770glc driver for the BH1770 and SFH7770 proximity
> > and ambient light sensor device.
>
> Remind me again why this isn't an drivers/iio/ driver, using that api?
Well, the driver is not written by me, I just found it as it is,
I tried to add new features and fix some bugs.
I can work on it if the supplier sends me a development board,
otherwise I cannot do much :(
> > In few words this is what it brings:
> > - /dev/input/event interface
> > - removal obsolete and wrong parameters
>
> What do you mean by this? Userspace parameters? Did you just change
> the user/kernel api? Or something else?
mainly user/kernel interfaces and some wrong parameters in the
Kernel. On the second version I'll update also Documentation/ABI.
For example one patch fixes some wrong frequencies that don't
match with the device properties.
Thanks again,
Andi
> > > > The driver generates an event in /dev/input/ under the name
> > > > 'bh1770'. It's a switch event where is reported '0' or '1'
> > > > whenever the sensor detects something crossing the threshold.
> > > >
> > > Doesn't this mean that this driver is now an "input" driver, so it
> > > shouldn't be using the odd sysfs api, and should move to the
> > > drivers/input/ directory tree?
> >
> > The driver has also lots of interfaces in
> > sysfs that are used from userspace, like proximity value and
> > ambient light value.
> >
> > What the input interface provides is just one of the features
> > from the driver. Shall I move it anyway?
>
> Hm, why not make it an iio driver instead? That way you get input and
> sysfs all together.
I'll do my best to get the hardware I need, then, so that once I
do it I'll do it fully correct :)
Then, just ignore this patches and I'll come later with a new
patchset.
But I still wonder: this is a combined proximity/ambient light
sensor, where exactly should I move it? Is it correct to create a
new directory for combined sensors?
Andi
On Tue, Jun 18, 2013 at 01:54:26AM +0200, Andi Shyti wrote:
> > > > > The driver generates an event in /dev/input/ under the name
> > > > > 'bh1770'. It's a switch event where is reported '0' or '1'
> > > > > whenever the sensor detects something crossing the threshold.
> > > > >
> > > > Doesn't this mean that this driver is now an "input" driver, so it
> > > > shouldn't be using the odd sysfs api, and should move to the
> > > > drivers/input/ directory tree?
> > >
> > > The driver has also lots of interfaces in
> > > sysfs that are used from userspace, like proximity value and
> > > ambient light value.
> > >
> > > What the input interface provides is just one of the features
> > > from the driver. Shall I move it anyway?
> >
> > Hm, why not make it an iio driver instead? That way you get input and
> > sysfs all together.
>
> I'll do my best to get the hardware I need, then, so that once I
> do it I'll do it fully correct :)
>
> Then, just ignore this patches and I'll come later with a new
> patchset.
>
> But I still wonder: this is a combined proximity/ambient light
> sensor, where exactly should I move it? Is it correct to create a
> new directory for combined sensors?
Ask the iio developers, they will know best here.
thanks,
greg k-h