From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
To: Jonathan Cameron <jic23@kernel.org>,
Lars-Peter Clausen <lars@metafoo.de>,
Rishi Gupta <gupt21@gmail.com>,
Matti Vaittinen <mazziesaccount@gmail.com>
Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
Jonathan Cameron <Jonathan.Cameron@huawei.com>,
Javier Carrasco <javier.carrasco.cruz@gmail.com>
Subject: [PATCH v2 1/4] iio: light: veml6030: extend regmap to support regfields
Date: Sun, 19 Jan 2025 18:31:58 +0100 [thread overview]
Message-ID: <20250119-veml6030-scale-v2-1-6bfc4062a371@gmail.com> (raw)
In-Reply-To: <20250119-veml6030-scale-v2-0-6bfc4062a371@gmail.com>
Add support for regfields as well to simplify register operations,
taking into account the different fields for the veml6030/veml7700 and
veml6035.
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
---
drivers/iio/light/veml6030.c | 95 ++++++++++++++++++++++++++++++++------------
1 file changed, 70 insertions(+), 25 deletions(-)
diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c
index 9b71825eea9bee2146be17ed2f30f5a8f7ad37e3..8e4eb8b0c19276635567d4eed74f4d402c3205fa 100644
--- a/drivers/iio/light/veml6030.c
+++ b/drivers/iio/light/veml6030.c
@@ -59,18 +59,31 @@
#define VEML6035_INT_CHAN BIT(3)
#define VEML6035_CHAN_EN BIT(2)
+/* Regfields */
+#define VEML6030_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 11, 12)
+#define VEML6030_IT_RF REG_FIELD(VEML6030_REG_ALS_CONF, 6, 9)
+
+#define VEML6035_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 10, 12)
+
enum veml6030_scan {
VEML6030_SCAN_ALS,
VEML6030_SCAN_WH,
VEML6030_SCAN_TIMESTAMP,
};
+struct veml6030_rf {
+ struct regmap_field *it;
+ struct regmap_field *gain;
+};
+
struct veml603x_chip {
const char *name;
const int(*scale_vals)[][2];
const int num_scale_vals;
const struct iio_chan_spec *channels;
const int num_channels;
+ const struct reg_field gain_rf;
+ const struct reg_field it_rf;
int (*hw_init)(struct iio_dev *indio_dev, struct device *dev);
int (*set_info)(struct iio_dev *indio_dev);
int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2);
@@ -91,6 +104,7 @@ struct veml603x_chip {
struct veml6030_data {
struct i2c_client *client;
struct regmap *regmap;
+ struct veml6030_rf rf;
int cur_resolution;
int cur_gain;
int cur_integration_time;
@@ -330,17 +344,17 @@ static const struct regmap_config veml6030_regmap_config = {
static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
int *val, int *val2)
{
- int ret, reg;
+ int it_idx, ret;
struct veml6030_data *data = iio_priv(indio_dev);
- ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®);
+ ret = regmap_field_read(data->rf.it, &it_idx);
if (ret) {
dev_err(&data->client->dev,
"can't read als conf register %d\n", ret);
return ret;
}
- switch ((reg >> 6) & 0xF) {
+ switch (it_idx) {
case 0:
*val2 = 100000;
break;
@@ -405,8 +419,7 @@ static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
return -EINVAL;
}
- ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
- VEML6030_ALS_IT, new_int_time);
+ ret = regmap_field_write(data->rf.it, new_int_time);
if (ret) {
dev_err(&data->client->dev,
"can't update als integration time %d\n", ret);
@@ -510,23 +523,22 @@ static int veml6030_set_als_gain(struct iio_dev *indio_dev,
struct veml6030_data *data = iio_priv(indio_dev);
if (val == 0 && val2 == 125000) {
- new_gain = 0x1000; /* 0x02 << 11 */
+ new_gain = 0x01;
gain_idx = 3;
} else if (val == 0 && val2 == 250000) {
- new_gain = 0x1800;
+ new_gain = 0x11;
gain_idx = 2;
} else if (val == 1 && val2 == 0) {
new_gain = 0x00;
gain_idx = 1;
} else if (val == 2 && val2 == 0) {
- new_gain = 0x800;
+ new_gain = 0x01;
gain_idx = 0;
} else {
return -EINVAL;
}
- ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
- VEML6030_ALS_GAIN, new_gain);
+ ret = regmap_field_write(data->rf.gain, new_gain);
if (ret) {
dev_err(&data->client->dev,
"can't set als gain %d\n", ret);
@@ -544,30 +556,31 @@ static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
struct veml6030_data *data = iio_priv(indio_dev);
if (val == 0 && val2 == 125000) {
- new_gain = VEML6035_SENS;
+ new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS);
gain_idx = 5;
} else if (val == 0 && val2 == 250000) {
- new_gain = VEML6035_SENS | VEML6035_GAIN;
+ new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
+ VEML6035_GAIN);
gain_idx = 4;
} else if (val == 0 && val2 == 500000) {
- new_gain = VEML6035_SENS | VEML6035_GAIN |
- VEML6035_DG;
+ new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
+ VEML6035_GAIN | VEML6035_DG);
gain_idx = 3;
} else if (val == 1 && val2 == 0) {
new_gain = 0x0000;
gain_idx = 2;
} else if (val == 2 && val2 == 0) {
- new_gain = VEML6035_GAIN;
+ new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN);
gain_idx = 1;
} else if (val == 4 && val2 == 0) {
- new_gain = VEML6035_GAIN | VEML6035_DG;
+ new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN |
+ VEML6035_DG);
gain_idx = 0;
} else {
return -EINVAL;
}
- ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
- VEML6035_GAIN_M, new_gain);
+ ret = regmap_field_write(data->rf.gain, new_gain);
if (ret) {
dev_err(&data->client->dev, "can't set als gain %d\n", ret);
return ret;
@@ -581,17 +594,17 @@ static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
static int veml6030_get_als_gain(struct iio_dev *indio_dev,
int *val, int *val2)
{
- int ret, reg;
+ int gain, ret;
struct veml6030_data *data = iio_priv(indio_dev);
- ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®);
+ ret = regmap_field_read(data->rf.gain, &gain);
if (ret) {
dev_err(&data->client->dev,
"can't read als conf register %d\n", ret);
return ret;
}
- switch ((reg >> 11) & 0x03) {
+ switch (gain) {
case 0:
*val = 1;
*val2 = 0;
@@ -617,17 +630,17 @@ static int veml6030_get_als_gain(struct iio_dev *indio_dev,
static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2)
{
- int ret, reg;
+ int gain, ret;
struct veml6030_data *data = iio_priv(indio_dev);
- ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®);
+ ret = regmap_field_read(data->rf.gain, &gain);
if (ret) {
dev_err(&data->client->dev,
- "can't read als conf register %d\n", ret);
+ "can't read als conf register %d\n", ret);
return ret;
}
- switch (FIELD_GET(VEML6035_GAIN_M, reg)) {
+ switch (gain) {
case 0:
*val = 1;
*val2 = 0;
@@ -990,6 +1003,27 @@ static int veml7700_set_info(struct iio_dev *indio_dev)
return 0;
}
+static int veml6030_regfield_init(struct iio_dev *indio_dev)
+{
+ struct veml6030_data *data = iio_priv(indio_dev);
+ struct regmap *regmap = data->regmap;
+ struct device *dev = &data->client->dev;
+ struct regmap_field *rm_field;
+ struct veml6030_rf *rf = &data->rf;
+
+ rm_field = devm_regmap_field_alloc(dev, regmap, data->chip->it_rf);
+ if (IS_ERR(rm_field))
+ return PTR_ERR(rm_field);
+ rf->it = rm_field;
+
+ rm_field = devm_regmap_field_alloc(dev, regmap, data->chip->gain_rf);
+ if (IS_ERR(rm_field))
+ return PTR_ERR(rm_field);
+ rf->gain = rm_field;
+
+ return 0;
+}
+
/*
* Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2,
* persistence to 1 x integration time and the threshold
@@ -1143,6 +1177,11 @@ static int veml6030_probe(struct i2c_client *client)
if (ret < 0)
return ret;
+ ret = veml6030_regfield_init(indio_dev);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "failed to init regfields\n");
+
ret = data->chip->hw_init(indio_dev, &client->dev);
if (ret < 0)
return ret;
@@ -1191,6 +1230,8 @@ static const struct veml603x_chip veml6030_chip = {
.num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
.channels = veml6030_channels,
.num_channels = ARRAY_SIZE(veml6030_channels),
+ .gain_rf = VEML6030_GAIN_RF,
+ .it_rf = VEML6030_IT_RF,
.hw_init = veml6030_hw_init,
.set_info = veml6030_set_info,
.set_als_gain = veml6030_set_als_gain,
@@ -1203,6 +1244,8 @@ static const struct veml603x_chip veml6035_chip = {
.num_scale_vals = ARRAY_SIZE(veml6035_scale_vals),
.channels = veml6030_channels,
.num_channels = ARRAY_SIZE(veml6030_channels),
+ .gain_rf = VEML6035_GAIN_RF,
+ .it_rf = VEML6030_IT_RF,
.hw_init = veml6035_hw_init,
.set_info = veml6030_set_info,
.set_als_gain = veml6035_set_als_gain,
@@ -1215,6 +1258,8 @@ static const struct veml603x_chip veml7700_chip = {
.num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
.channels = veml7700_channels,
.num_channels = ARRAY_SIZE(veml7700_channels),
+ .gain_rf = VEML6030_GAIN_RF,
+ .it_rf = VEML6030_IT_RF,
.hw_init = veml6030_hw_init,
.set_info = veml7700_set_info,
.set_als_gain = veml6030_set_als_gain,
--
2.43.0
next prev parent reply other threads:[~2025-01-19 17:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-19 17:31 [PATCH v2 0/4] iio: light: fix scale in veml6030 Javier Carrasco
2025-01-19 17:31 ` Javier Carrasco [this message]
2025-01-19 17:31 ` [PATCH v2 2/4] iio: light: veml6030: extend regmap to support caching Javier Carrasco
2025-01-19 17:32 ` [PATCH v2 3/4] iio: gts-helper: export iio_gts_get_total_gain() Javier Carrasco
2025-01-24 8:12 ` Matti Vaittinen
2025-01-25 20:08 ` Javier Carrasco
2025-01-19 17:32 ` [PATCH v2 4/4] iio: light: veml6030: fix scale to conform to ABI Javier Carrasco
2025-01-24 8:24 ` Matti Vaittinen
2025-01-25 12:33 ` [PATCH v2 0/4] iio: light: fix scale in veml6030 Jonathan Cameron
2025-01-25 20:12 ` Javier Carrasco
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250119-veml6030-scale-v2-1-6bfc4062a371@gmail.com \
--to=javier.carrasco.cruz@gmail.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=gupt21@gmail.com \
--cc=jic23@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mazziesaccount@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®