From e636c8d336489bf3eed5878299e6cc045bbad077 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:17:29 +0000
Subject: [PATCH] debug lk
---
kernel/drivers/iio/light/al3320a.c | 79 ++++++++++++++++++++++++++++-----------
1 files changed, 56 insertions(+), 23 deletions(-)
diff --git a/kernel/drivers/iio/light/al3320a.c b/kernel/drivers/iio/light/al3320a.c
index 66623fa..cc1407c 100644
--- a/kernel/drivers/iio/light/al3320a.c
+++ b/kernel/drivers/iio/light/al3320a.c
@@ -1,21 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* AL3320A - Dyna Image Ambient Light Sensor
*
* Copyright (c) 2014, Intel Corporation.
*
- * This file is subject to the terms and conditions of version 2 of
- * the GNU General Public License. See the file COPYING in the main
- * directory of this archive for more details.
- *
* IIO driver for AL3320A (7-bit I2C slave address 0x1C).
*
* TODO: interrupt support, thresholds
- *
+ * When the driver will get support for interrupt handling, then interrupt
+ * will need to be disabled before turning sensor OFF in order to avoid
+ * potential races with the interrupt handling.
*/
-#include <linux/module.h>
-#include <linux/init.h>
+#include <linux/bitfield.h>
#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -40,8 +40,7 @@
#define AL3320A_CONFIG_DISABLE 0x00
#define AL3320A_CONFIG_ENABLE 0x01
-#define AL3320A_GAIN_SHIFT 1
-#define AL3320A_GAIN_MASK (BIT(2) | BIT(1))
+#define AL3320A_GAIN_MASK GENMASK(2, 1)
/* chip params default values */
#define AL3320A_DEFAULT_MEAN_TIME 4
@@ -83,18 +82,31 @@
.attrs = al3320a_attributes,
};
+static int al3320a_set_pwr(struct i2c_client *client, bool pwr)
+{
+ u8 val = pwr ? AL3320A_CONFIG_ENABLE : AL3320A_CONFIG_DISABLE;
+ return i2c_smbus_write_byte_data(client, AL3320A_REG_CONFIG, val);
+}
+
+static void al3320a_set_pwr_off(void *_data)
+{
+ struct al3320a_data *data = _data;
+
+ al3320a_set_pwr(data->client, false);
+}
+
static int al3320a_init(struct al3320a_data *data)
{
int ret;
- /* power on */
- ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_CONFIG,
- AL3320A_CONFIG_ENABLE);
+ ret = al3320a_set_pwr(data->client, true);
+
if (ret < 0)
return ret;
ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_CONFIG_RANGE,
- AL3320A_RANGE_3 << AL3320A_GAIN_SHIFT);
+ FIELD_PREP(AL3320A_GAIN_MASK,
+ AL3320A_RANGE_3));
if (ret < 0)
return ret;
@@ -137,7 +149,7 @@
if (ret < 0)
return ret;
- ret = (ret & AL3320A_GAIN_MASK) >> AL3320A_GAIN_SHIFT;
+ ret = FIELD_GET(AL3320A_GAIN_MASK, ret);
*val = al3320a_scales[ret][0];
*val2 = al3320a_scales[ret][1];
@@ -156,11 +168,13 @@
switch (mask) {
case IIO_CHAN_INFO_SCALE:
for (i = 0; i < ARRAY_SIZE(al3320a_scales); i++) {
- if (val == al3320a_scales[i][0] &&
- val2 == al3320a_scales[i][1])
- return i2c_smbus_write_byte_data(data->client,
+ if (val != al3320a_scales[i][0] ||
+ val2 != al3320a_scales[i][1])
+ continue;
+
+ return i2c_smbus_write_byte_data(data->client,
AL3320A_REG_CONFIG_RANGE,
- i << AL3320A_GAIN_SHIFT);
+ FIELD_PREP(AL3320A_GAIN_MASK, i));
}
break;
}
@@ -188,7 +202,6 @@
i2c_set_clientdata(client, indio_dev);
data->client = client;
- indio_dev->dev.parent = &client->dev;
indio_dev->info = &al3320a_info;
indio_dev->name = AL3320A_DRV_NAME;
indio_dev->channels = al3320a_channels;
@@ -200,14 +213,27 @@
dev_err(&client->dev, "al3320a chip init failed\n");
return ret;
}
+
+ ret = devm_add_action_or_reset(&client->dev,
+ al3320a_set_pwr_off,
+ data);
+ if (ret < 0)
+ return ret;
+
return devm_iio_device_register(&client->dev, indio_dev);
}
-static int al3320a_remove(struct i2c_client *client)
+static int __maybe_unused al3320a_suspend(struct device *dev)
{
- return i2c_smbus_write_byte_data(client, AL3320A_REG_CONFIG,
- AL3320A_CONFIG_DISABLE);
+ return al3320a_set_pwr(to_i2c_client(dev), false);
}
+
+static int __maybe_unused al3320a_resume(struct device *dev)
+{
+ return al3320a_set_pwr(to_i2c_client(dev), true);
+}
+
+static SIMPLE_DEV_PM_OPS(al3320a_pm_ops, al3320a_suspend, al3320a_resume);
static const struct i2c_device_id al3320a_id[] = {
{"al3320a", 0},
@@ -215,12 +241,19 @@
};
MODULE_DEVICE_TABLE(i2c, al3320a_id);
+static const struct of_device_id al3320a_of_match[] = {
+ { .compatible = "dynaimage,al3320a", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, al3320a_of_match);
+
static struct i2c_driver al3320a_driver = {
.driver = {
.name = AL3320A_DRV_NAME,
+ .of_match_table = al3320a_of_match,
+ .pm = &al3320a_pm_ops,
},
.probe = al3320a_probe,
- .remove = al3320a_remove,
.id_table = al3320a_id,
};
--
Gitblit v1.6.2