misc: bh1770glc features and fixes
cover misc: bh1770glc features and fixes
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(-)
Signature · 1 line
1.7.10.4
PATCH 1/19 bh1770glc: added input device interface
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.
--- drivers/misc/bh1770glc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-)
drivers/misc/bh1770glc.c +57 -1
@@ -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 ();
Signature · 1 line
1.7.10.4
Greg KH
maintainerRe: [PATCH 01/19] bh1770glc: added input device interface
Quoted 10 lines · Andi Shyti
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
Re: [PATCH 01/19] bh1770glc: added input device interface
Hi Greg,
Quoted 11 lines
Quoted 10 lines
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(-)
Quoted 3 lines
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
Greg KH
maintainerRe: [PATCH 01/19] bh1770glc: added input device interface
Quoted 17 lines · Andi Shyti
Hi Greg,
Quoted 11 lines
Quoted 10 lines
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(-)Quoted 3 lines
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?
Quoted 6 lines
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
Re: [PATCH 01/19] bh1770glc: added input device interface
Quoted 12 lines
Quoted 12 lines
Quoted 7 lines
Quoted 4 lines
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.
Quoted 5 lines
Quoted 2 lines
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
Greg KH
maintainerRe: [PATCH 01/19] bh1770glc: added input device interface
Quoted 21 lines · Andi Shyti
Quoted 12 lines
Quoted 12 lines
Quoted 7 lines
Quoted 4 lines
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.Quoted 5 lines
Quoted 2 lines
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 :)
Quoted 6 lines
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
PATCH 2/19 bh1770glc: different glass attenuation parameters
In reply to Andi ShytiFrom: 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.
--- include/linux/i2c/bh1770glc.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/i2c/bh1770glc.h +2 -0
@@ -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 ); };
Signature · 1 line
1.7.10.4
PATCH 3/19 bh1770glc: lux0_glass_factor & lux0_comp_factor on sysfs
In reply to Andi ShytiFrom: 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.
--- drivers/misc/bh1770glc.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/misc/bh1770glc.c +22 -0
@@ -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,
Signature · 1 line
1.7.10.4
Greg KH
maintainerRe: [PATCH 03/19] bh1770glc: lux0_glass_factor & lux0_comp_factor on sysfs
Quoted 6 lines · Andi Shyti
From: Onur Atilla <[email protected]>
Introduced
lux0_glass_factorandlux0_comp_factoron sysfs
lux0_glass_factorandlux0_sensor_comp_factorare 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
Re: [PATCH 03/19] bh1770glc: lux0_glass_factor & lux0_comp_factor on sysfs
Quoted 8 lines
Quoted 4 lines
Introduced
lux0_glass_factorandlux0_comp_factoron sysfs
lux0_glass_factorandlux0_sensor_comp_factorare 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/ABIchanges as well. Please redo this patch with those updates.
Right! missed that, I'll resend it
Andi
PATCH 4/19 bh1770glc: Added raw lux output file for ALS to sysfs
In reply to Andi ShytiFrom: 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.
--- drivers/misc/bh1770glc.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
drivers/misc/bh1770glc.c +31 -0
@@ -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,
Signature · 1 line
1.7.10.4
PATCH 5/19 bh1770glc: Removed obsolete offset settings from SFH7770 code
In reply to Andi ShytiFrom: 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.
--- drivers/misc/bh1770glc.c | 3 --- 1 file changed, 3 deletions(-)
drivers/misc/bh1770glc.c +0 -3
@@ -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 ; }
Signature · 1 line
1.7.10.4
PATCH 6/19 bh1770glc: removed proximity adjustement
In reply to Andi Shytiproximity sensor doesn't need to be adjusted; removed all the overcode used for the proximity coefficients
--- drivers/misc/bh1770glc.c | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-)
drivers/misc/bh1770glc.c +2 -37
@@ -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)
Signature · 1 line
1.7.10.4
PATCH 7/19 bh1770glc: split read result function
In reply to Andi Shytiprox_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
--- drivers/misc/bh1770glc.c | 53 +++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 19 deletions(-)
drivers/misc/bh1770glc.c +34 -19
@@ -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; }
Signature · 1 line
1.7.10.4
PATCH 8/19 bh1770glc: logic change in the proximity read
In reply to Andi Shytithe 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
--- drivers/misc/bh1770glc.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/misc/bh1770glc.c +5 -0
@@ -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
Signature · 1 line
1.7.10.4
PATCH 9/19 bh1770glc: use min_t instead of min
In reply to Andi Shyti--- drivers/misc/bh1770glc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/misc/bh1770glc.c +1 -1
@@ -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,
Signature · 1 line
1.7.10.4
PATCH 10/19 bh1770glc: use kstrtoul instead of strict_strtoul
In reply to Andi Shytikstrtoul() 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.
--- drivers/misc/bh1770glc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/misc/bh1770glc.c +10 -10
@@ -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 )
Signature · 1 line
1.7.10.4
PATCH 11/19 bh1770glc: removed lux_read_raw_result() function
In reply to Andi Shytilux_raw_result_show() will run directly the lux_get_result() instead of using another support function
--- drivers/misc/bh1770glc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/misc/bh1770glc.c +2 -7
@@ -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;
Signature · 1 line
1.7.10.4
PATCH 12/19 bh1770glc: Introduced dynamic threshold
In reply to Andi ShytiFrom: 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.
--- drivers/misc/bh1770glc.c | 96 +++++++++++++++++++++++++---------------- include/linux/i2c/bh1770glc.h | 3 ++ 2 files changed, 61 insertions(+), 38 deletions(-)
drivers/misc/bh1770glc.c +58 -38
@@ -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);
include/linux/i2c/bh1770glc.h +3 -0
@@ -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 ); };
Signature · 1 line
1.7.10.4
PATCH 13/19 bh1770glc: Code cleaning and aligning in source code
In reply to Andi ShytiFrom: Onur Atilla <[email protected]>
Removed unused variables and definitions, adjusted some code alignement and removed trailing spaces.
--- drivers/misc/bh1770glc.c | 55 +++++++++++++++++++---------------------- include/linux/i2c/bh1770glc.h | 25 ++++++++++--------- 2 files changed, 38 insertions(+), 42 deletions(-)
drivers/misc/bh1770glc.c +25 -30
@@ -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;
include/linux/i2c/bh1770glc.h +13 -12
@@ -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;
Signature · 1 line
1.7.10.4
PATCH 14/19 bh1770glc: Modified the neutral glass attenuation value
In reply to Andi ShytiFrom: Onur Atilla <[email protected]>
Changed the neutral glass attenuation value from 16384 to 8192. This is for adaptation to the new scaling factor.
--- include/linux/i2c/bh1770glc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/i2c/bh1770glc.h +2 -2
@@ -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 */
Signature · 1 line
1.7.10.4
PATCH 15/19 bh1770glc: Modified scaler variable
In reply to Andi ShytiFrom: Onur Atilla <[email protected]>
Changed all exposed scalers to 8192 (Q13) in order to achieve consistency in the sysfs interface.
--- drivers/misc/bh1770glc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/misc/bh1770glc.c +2 -2
@@ -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
Signature · 1 line
1.7.10.4
PATCH 16/19 bh1770glc: Added sanity check for scf
In reply to Andi ShytiFrom: Onur Atilla <[email protected]>
Sensor compensation factor input from the platform is being checked now before use.
--- drivers/misc/bh1770glc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/misc/bh1770glc.c +11 -2
@@ -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) &&
Signature · 1 line
1.7.10.4
PATCH 17/19 bh1770glc: Implemented switch for interrupt operation
In reply to Andi ShytiFrom: 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.
--- drivers/misc/bh1770glc.c | 10 ++++++++++ include/linux/i2c/bh1770glc.h | 1 + 2 files changed, 11 insertions(+)
drivers/misc/bh1770glc.c +10 -0
@@ -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
include/linux/i2c/bh1770glc.h +1 -0
@@ -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 ); };
Signature · 1 line
1.7.10.4
PATCH 18/19 bh1770glc: Corrected proximity sensor rates
In reply to Andi ShytiFrom: 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.
--- drivers/misc/bh1770glc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/misc/bh1770glc.c +3 -3
@@ -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 };
Signature · 1 line
1.7.10.4
PATCH 19/19 bh1770glc: Proximity sensor LED current update
In reply to Andi ShytiFrom: 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.
--- drivers/misc/bh1770glc.c | 11 ++++++++++- include/linux/i2c/bh1770glc.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-)
drivers/misc/bh1770glc.c +10 -1
@@ -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 ;
include/linux/i2c/bh1770glc.h +1 -0
@@ -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;
Signature · 1 line
1.7.10.4
Greg KH
maintainerQuoted 5 lines · Andi Shyti
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?
Quoted 3 lines
In few words this is what it brings:
-/dev/input/eventinterface
- removal obsolete and wrong parameters
What do you mean by this? Userspace parameters? Did you just change the user/kernel api? Or something else?
Quoted 2 lines
- 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
Quoted 5 lines
Quoted 3 lines
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 :(
Quoted 6 lines
Quoted 3 lines
In few words this is what it brings:
-/dev/input/eventinterface
- removal obsolete and wrong parametersWhat 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