Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f2e06ac authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "input: sensors: add enable handler for mma8x5x"

parents 2ee35475 eaf6a6e1
Loading
Loading
Loading
Loading
+78 −42
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 *  mma8x5x.c - Linux kernel modules for 3-Axis Orientation/Motion
 *  Detection Sensor MMA8451/MMA8452/MMA8453
 *
 *  Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
 *  Copyright (c) 2013-2014, The Linux Foundation. All Rights Reserved.
 *  Linux Foundation chooses to take subject only to the GPLv2 license
 *  terms, and distributes only under these terms.
 *  Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
@@ -68,6 +68,10 @@ static struct sensors_classdev sensors_cdev = {
	.min_delay = 2000,
	.fifo_reserved_event_count = 0,
	.fifo_max_event_count = 0,
	.enabled = 0,
	.delay_msec = POLL_INTERVAL,
	.sensors_enable = NULL,
	.sensors_poll_delay = NULL,
};

struct sensor_regulator {
@@ -162,6 +166,7 @@ struct mma8x5x_data {
	struct i2c_client *client;
	struct input_polled_dev *poll_dev;
	struct mutex data_lock;
	struct sensors_classdev cdev;
	int active;
	int position;
	u8 chip_id;
@@ -391,41 +396,16 @@ static void mma8x5x_dev_poll(struct input_polled_dev *dev)
	mma8x5x_report_data(pdata);
}

static ssize_t mma8x5x_enable_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
	struct i2c_client *client = pdata->client;
	u8 val;
	int enable;

	mutex_lock(&pdata->data_lock);
	val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
	if ((val & 0x01) && pdata->active == MMA_ACTIVED)
		enable = 1;
	else
		enable = 0;
	mutex_unlock(&pdata->data_lock);
	return snprintf(buf, PAGE_SIZE, "%d\n", enable);
}

static ssize_t mma8x5x_enable_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
static int mma8x5x_enable_set(struct sensors_classdev *sensors_cdev,
		unsigned int enable)
{
	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
	struct mma8x5x_data *pdata = container_of(sensors_cdev,
			struct mma8x5x_data, cdev);
	struct i2c_client *client = pdata->client;
	int ret;
	unsigned long enable;
	u8 val = 0;

	ret = kstrtoul(buf, 10, &enable);
	if (ret)
		return ret;
	mutex_lock(&pdata->data_lock);
	enable = (enable > 0) ? 1 : 0;
	if (enable) {
		if (pdata->active & MMA_SHUTTEDDOWN) {
			ret = mma8x5x_config_regulator(client, 1);
@@ -442,7 +422,7 @@ static ssize_t mma8x5x_enable_store(struct device *dev,
			val = i2c_smbus_read_byte_data(client,
					MMA8X5X_CTRL_REG1);
			if (val < 0) {
				dev_err(dev, "read device state failed!");
				dev_err(&client->dev, "read device state failed!");
				ret = val;
				goto err_failed;
			}
@@ -450,11 +430,11 @@ static ssize_t mma8x5x_enable_store(struct device *dev,
			ret = i2c_smbus_write_byte_data(client,
					MMA8X5X_CTRL_REG1, val | 0x01);
			if (ret) {
				dev_err(dev, "change device state failed!");
				dev_err(&client->dev, "change device state failed!");
				goto err_failed;
			}
			pdata->active = MMA_ACTIVED;
			dev_dbg(dev, "%s:mma enable setting active.\n",
			dev_dbg(&client->dev, "%s:mma enable setting active.\n",
					__func__);
		}
	} else if (enable == 0) {
@@ -462,7 +442,7 @@ static ssize_t mma8x5x_enable_store(struct device *dev,
			val = i2c_smbus_read_byte_data(client,
					MMA8X5X_CTRL_REG1);
			if (val < 0) {
				dev_err(dev, "read device state failed!");
				dev_err(&client->dev, "read device state failed!");
				ret = val;
				goto err_failed;
			}
@@ -470,24 +450,62 @@ static ssize_t mma8x5x_enable_store(struct device *dev,
			ret = i2c_smbus_write_byte_data(client,
				MMA8X5X_CTRL_REG1, val & 0xFE);
			if (ret) {
				dev_err(dev, "change device state failed!");
				dev_err(&client->dev, "change device state failed!");
				goto err_failed;
			}

			pdata->active = MMA_STANDBY;
			dev_dbg(dev, "%s:mma enable setting inactive.\n",
			dev_dbg(&client->dev, "%s:mma enable setting inactive.\n",
					__func__);
		}
		if (!mma8x5x_config_regulator(client, 0))
			pdata->active |= MMA_SHUTTEDDOWN;
	}
	mutex_unlock(&pdata->data_lock);
	return count;
	return 0;

err_failed:
	mutex_unlock(&pdata->data_lock);
	return ret;
}

static ssize_t mma8x5x_enable_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
	struct i2c_client *client = pdata->client;
	u8 val;
	int enable;

	mutex_lock(&pdata->data_lock);
	val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
	if ((val & 0x01) && pdata->active == MMA_ACTIVED)
		enable = 1;
	else
		enable = 0;
	mutex_unlock(&pdata->data_lock);
	return snprintf(buf, PAGE_SIZE, "%d\n", enable);
}

static ssize_t mma8x5x_enable_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
	struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
	int ret;
	unsigned long enable;

	ret = kstrtoul(buf, 10, &enable);
	if (ret)
		return ret;
	enable = (enable > 0) ? 1 : 0;
	ret = mma8x5x_enable_set(&pdata->cdev, enable);
	if (ret < 0)
		return ret;
	return count;
}
static ssize_t mma8x5x_position_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
@@ -517,6 +535,20 @@ static ssize_t mma8x5x_position_store(struct device *dev,
	return count;
}

static int mma8x5x_poll_delay_set(struct sensors_classdev *sensors_cdev,
		unsigned int delay_ms)
{
	struct mma8x5x_data *pdata = container_of(sensors_cdev,
			struct mma8x5x_data, cdev);

	mutex_lock(&pdata->data_lock);
	pdata->poll_delay = delay_ms;
	pdata->poll_dev->poll_interval = pdata->poll_delay;
	mutex_unlock(&pdata->data_lock);

	return 0;
}

static ssize_t mma8x5x_poll_delay_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
@@ -540,10 +572,9 @@ static ssize_t mma8x5x_poll_delay_store(struct device *dev,
		interval = POLL_INTERVAL_MIN;
	if (interval > POLL_INTERVAL_MAX)
		interval = POLL_INTERVAL_MAX;
	mutex_lock(&pdata->data_lock);
	pdata->poll_delay = interval;
	poll_dev->poll_interval = pdata->poll_delay;
	mutex_unlock(&pdata->data_lock);

	mma8x5x_poll_delay_set(&pdata->cdev, interval);

	return count;
}

@@ -694,7 +725,12 @@ static int mma8x5x_probe(struct i2c_client *client,
		result = -EINVAL;
		goto err_create_sysfs;
	}
	result = sensors_classdev_register(&client->dev, &sensors_cdev);
	pdata->cdev = sensors_cdev;
	pdata->cdev.min_delay = POLL_INTERVAL_MIN * 1000;
	pdata->cdev.delay_msec = poll_dev->poll_interval;
	pdata->cdev.sensors_enable = mma8x5x_enable_set;
	pdata->cdev.sensors_poll_delay = mma8x5x_poll_delay_set;
	result = sensors_classdev_register(&client->dev, &pdata->cdev);
	if (result) {
		dev_err(&client->dev, "create class device file failed!\n");
		result = -EINVAL;