aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/mfld-sensors/apds9802ps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/mfld-sensors/apds9802ps.c')
-rw-r--r--drivers/staging/mfld-sensors/apds9802ps.c106
1 files changed, 61 insertions, 45 deletions
diff --git a/drivers/staging/mfld-sensors/apds9802ps.c b/drivers/staging/mfld-sensors/apds9802ps.c
index 6379e1a11ee..8fbd50937d4 100644
--- a/drivers/staging/mfld-sensors/apds9802ps.c
+++ b/drivers/staging/mfld-sensors/apds9802ps.c
@@ -25,12 +25,10 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
-#include <linux/hwmon-sysfs.h>
MODULE_AUTHOR("Anantha Narayanan <Anantha.Narayanan@intel.com");
MODULE_DESCRIPTION("Avago apds9802ps Proximity Driver");
@@ -42,26 +40,33 @@ MODULE_LICENSE("GPL v2");
#define DRIVER_NAME "apds9802ps"
struct ps_data{
- struct device *hwmon_dev;
- bool needresume;
- struct mutex write_lock;
+ struct mutex lock;
};
+
static ssize_t ps_proximity_output_data_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
- unsigned int ret_val = 0;
- unsigned int tempv1, tempv2;
-
- tempv1 = i2c_smbus_read_byte_data(client, 0x85); /* LSB data */
- if (tempv1 < 0)
- printk(KERN_WARNING " apds9802ps: failed proximity out read LSB\n");
- tempv2 = i2c_smbus_read_byte_data(client, 0x86); /* MSB data */
- if (tempv2 < 0)
- printk(KERN_WARNING " apds9802ps: failed proximity out read MSB\n");
- ret_val = (tempv2 << 8 | tempv1);
+ struct ps_data *data = i2c_get_clientdata(client);
+ int ret_val = 0;
+ int l, h;
+
+ mutex_lock(&data->lock);
+
+ l = i2c_smbus_read_byte_data(client, 0x85); /* LSB data */
+ if (l < 0)
+ dev_warn(dev, "failed proximity out read LSB\n");
+
+ h = i2c_smbus_read_byte_data(client, 0x86); /* MSB data */
+ if (h < 0)
+ dev_warn(dev, "failed proximity out read MSB\n");
+
+ mutex_unlock(&data->lock);
+
+ ret_val = (h << 8 | l);
return sprintf(buf, "%d\n", ret_val);
}
+
static ssize_t ps_power_status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -70,30 +75,35 @@ static ssize_t ps_power_status_show(struct device *dev,
ret_val = i2c_smbus_read_byte_data(client, 0x80);
if (ret_val < 0)
- printk(KERN_WARNING " apds9802ps: failed power status read MSB\n");
- ret_val = ret_val & 0x01;
+ dev_warn(dev, "failed power status read\n");
+
+ ret_val = ret_val & 0x01;
return sprintf(buf, "%d\n", ret_val);
}
+
static void ps_set_power_state(struct i2c_client *client, bool on_off)
{
char curr_val = 0;
struct ps_data *data = i2c_get_clientdata(client);
- mutex_lock(&data->write_lock);
+ mutex_lock(&data->lock);
+
curr_val = i2c_smbus_read_byte_data(client, 0x80);
if (on_off)
curr_val = curr_val | 0x01;
else
curr_val = curr_val & 0xFE;
+
if (i2c_smbus_write_byte_data(client, 0x80, curr_val) < 0)
- printk(KERN_WARNING " apds9802ps: failed power state write\n");
- mutex_unlock(&data->write_lock);
+ dev_warn(&client->dev, "failed power state write\n");
+
+ mutex_unlock(&data->lock);
}
+
static ssize_t ps_power_status_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
- struct ps_data *data = i2c_get_clientdata(client);
unsigned long val = 0;
if (strict_strtoul(buf, 10, &val))
@@ -101,17 +111,18 @@ static ssize_t ps_power_status_store(struct device *dev,
if (val == POWER_STA_ENABLE) {
ps_set_power_state(client, true);
- data->needresume = true;
} else if (val == POWER_STA_DISABLE) {
ps_set_power_state(client, false);
- data->needresume = false;
} else
return -EINVAL;
+
return count;
}
-static DEVICE_ATTR(proximity_output, S_IRUGO, ps_proximity_output_data_show, NULL);
+
+static DEVICE_ATTR(proximity_output, S_IRUGO,
+ ps_proximity_output_data_show, NULL);
static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
- ps_power_status_show, ps_power_status_store);
+ ps_power_status_show, ps_power_status_store);
static struct attribute *mid_att_ps[] = {
&dev_attr_proximity_output.attr,
@@ -123,40 +134,45 @@ static struct attribute_group m_ps_gr = {
.name = "apds9802ps",
.attrs = mid_att_ps
};
+
static void ps_set_default_config(struct i2c_client *client)
{
- /*Power ON */
+ /* Power ON */
if (i2c_smbus_write_byte_data(client, 0x80, 0x01) < 0)
- printk(KERN_WARNING " apds9802ps: failed default power on write\n");
- /* 20 pulses, 100Khz Pulse frequency*/
+ dev_warn(&client->dev, "failed default power on write\n");
+
+ /* 20 pulses, 100Khz Pulse frequency */
if (i2c_smbus_write_byte_data(client, 0x81, 0x86) < 0)
- printk(KERN_WARNING " apds9802ps: failed pulse frequency write\n");
- /*Enable measurement, 100MA LED current*/
+ dev_warn(&client->dev, "failed pulse frequency write\n");
+
+ /* Enable measurement, 100MA LED current */
if (i2c_smbus_write_byte_data(client, 0x82, 0x28) < 0)
- printk(KERN_WARNING " apds9802ps: failed enable measurement write\n");
+ dev_warn(&client->dev, "failed enable measurement write\n");
}
-static int apds9802ps_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+
+static int apds9802ps_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int res;
struct ps_data *data;
data = kzalloc(sizeof(struct ps_data), GFP_KERNEL);
if (data == NULL) {
- printk(KERN_WARNING " apds9802ps: Memory initialization failed");
+ dev_err(&client->dev, "alloc ps_data failed\n");
return -ENOMEM;
}
i2c_set_clientdata(client, data);
res = sysfs_create_group(&client->dev.kobj, &m_ps_gr);
if (res) {
- printk(KERN_WARNING "apds9802ps: device create file failed!!\n");
+ dev_err(&client->dev, "sysfs file create failed\n");
goto ps_error1;
}
- dev_info(&client->dev, "%s apds9802ps:chipfound\n", client->name);
+
+ dev_info(&client->dev, "proximity sensor chip found\n");
+
ps_set_default_config(client);
- data->needresume = true;
- mutex_init(&data->write_lock);
+ mutex_init(&data->lock);
return res;
ps_error1:
@@ -169,22 +185,24 @@ static int apds9802ps_remove(struct i2c_client *client)
{
struct ps_data *data = i2c_get_clientdata(client);
+ ps_set_power_state(client, false);
sysfs_remove_group(&client->dev.kobj, &m_ps_gr);
kfree(data);
return 0;
}
+
static int apds9802ps_suspend(struct i2c_client *client, pm_message_t mesg)
{
ps_set_power_state(client, false);
return 0;
}
+
static int apds9802ps_resume(struct i2c_client *client)
{
- struct ps_data *data = i2c_get_clientdata(client);
- if (data->needresume == true)
- ps_set_power_state(client, true);
+ ps_set_power_state(client, true);
return 0;
}
+
static struct i2c_device_id apds9802ps_id[] = {
{ DRIVER_NAME, 0 },
{ }
@@ -206,9 +224,7 @@ static struct i2c_driver apds9802ps_driver = {
static int __init sensor_apds9802ps_init(void)
{
- int res;
- res = i2c_add_driver(&apds9802ps_driver);
- return res;
+ return i2c_add_driver(&apds9802ps_driver);
}
static void __exit sensor_apds9802ps_exit(void)