diff options
Diffstat (limited to 'drivers/iio/light/al3320a.c')
-rw-r--r-- | drivers/iio/light/al3320a.c | 116 |
1 files changed, 63 insertions, 53 deletions
diff --git a/drivers/iio/light/al3320a.c b/drivers/iio/light/al3320a.c index 497ea3fe3377..63f5a85912fc 100644 --- a/drivers/iio/light/al3320a.c +++ b/drivers/iio/light/al3320a.c @@ -15,13 +15,12 @@ #include <linux/bitfield.h> #include <linux/i2c.h> #include <linux/module.h> +#include <linux/regmap.h> #include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#define AL3320A_DRV_NAME "al3320a" - #define AL3320A_REG_CONFIG 0x00 #define AL3320A_REG_STATUS 0x01 #define AL3320A_REG_INT 0x02 @@ -59,8 +58,14 @@ static const int al3320a_scales[][2] = { {0, 512000}, {0, 128000}, {0, 32000}, {0, 10000} }; +static const struct regmap_config al3320a_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = AL3320A_REG_HIGH_THRESH_HIGH, +}; + struct al3320a_data { - struct i2c_client *client; + struct regmap *regmap; }; static const struct iio_chan_spec al3320a_channels[] = { @@ -82,45 +87,47 @@ static const struct attribute_group al3320a_attribute_group = { .attrs = al3320a_attributes, }; -static int al3320a_set_pwr(struct i2c_client *client, bool pwr) +static int al3320a_set_pwr_on(struct al3320a_data *data) { - u8 val = pwr ? AL3320A_CONFIG_ENABLE : AL3320A_CONFIG_DISABLE; - return i2c_smbus_write_byte_data(client, AL3320A_REG_CONFIG, val); + return regmap_write(data->regmap, AL3320A_REG_CONFIG, AL3320A_CONFIG_ENABLE); } static void al3320a_set_pwr_off(void *_data) { struct al3320a_data *data = _data; + struct device *dev = regmap_get_device(data->regmap); + int ret; - al3320a_set_pwr(data->client, false); + ret = regmap_write(data->regmap, AL3320A_REG_CONFIG, AL3320A_CONFIG_DISABLE); + if (ret) + dev_err(dev, "failed to write system register\n"); } static int al3320a_init(struct al3320a_data *data) { + struct device *dev = regmap_get_device(data->regmap); int ret; - ret = al3320a_set_pwr(data->client, true); - - if (ret < 0) + ret = al3320a_set_pwr_on(data); + if (ret) return ret; - ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_CONFIG_RANGE, - FIELD_PREP(AL3320A_GAIN_MASK, - AL3320A_RANGE_3)); - if (ret < 0) + ret = devm_add_action_or_reset(dev, al3320a_set_pwr_off, data); + if (ret) return ret; - ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_MEAN_TIME, - AL3320A_DEFAULT_MEAN_TIME); - if (ret < 0) + ret = regmap_write(data->regmap, AL3320A_REG_CONFIG_RANGE, + FIELD_PREP(AL3320A_GAIN_MASK, AL3320A_RANGE_3)); + if (ret) return ret; - ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_WAIT, - AL3320A_DEFAULT_WAIT_TIME); - if (ret < 0) + ret = regmap_write(data->regmap, AL3320A_REG_MEAN_TIME, + AL3320A_DEFAULT_MEAN_TIME); + if (ret) return ret; - return 0; + return regmap_write(data->regmap, AL3320A_REG_WAIT, + AL3320A_DEFAULT_WAIT_TIME); } static int al3320a_read_raw(struct iio_dev *indio_dev, @@ -128,7 +135,7 @@ static int al3320a_read_raw(struct iio_dev *indio_dev, int *val2, long mask) { struct al3320a_data *data = iio_priv(indio_dev); - int ret; + int ret, gain, raw; switch (mask) { case IIO_CHAN_INFO_RAW: @@ -137,21 +144,21 @@ static int al3320a_read_raw(struct iio_dev *indio_dev, * - low byte of output is stored at AL3320A_REG_DATA_LOW * - high byte of output is stored at AL3320A_REG_DATA_LOW + 1 */ - ret = i2c_smbus_read_word_data(data->client, - AL3320A_REG_DATA_LOW); - if (ret < 0) + ret = regmap_read(data->regmap, AL3320A_REG_DATA_LOW, &raw); + if (ret) return ret; - *val = ret; + + *val = raw; + return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - ret = i2c_smbus_read_byte_data(data->client, - AL3320A_REG_CONFIG_RANGE); - if (ret < 0) + ret = regmap_read(data->regmap, AL3320A_REG_CONFIG_RANGE, &gain); + if (ret) return ret; - ret = FIELD_GET(AL3320A_GAIN_MASK, ret); - *val = al3320a_scales[ret][0]; - *val2 = al3320a_scales[ret][1]; + gain = FIELD_GET(AL3320A_GAIN_MASK, gain); + *val = al3320a_scales[gain][0]; + *val2 = al3320a_scales[gain][1]; return IIO_VAL_INT_PLUS_MICRO; } @@ -163,7 +170,7 @@ static int al3320a_write_raw(struct iio_dev *indio_dev, int val2, long mask) { struct al3320a_data *data = iio_priv(indio_dev); - int i; + unsigned int i; switch (mask) { case IIO_CHAN_INFO_SCALE: @@ -172,9 +179,8 @@ static int al3320a_write_raw(struct iio_dev *indio_dev, val2 != al3320a_scales[i][1]) continue; - return i2c_smbus_write_byte_data(data->client, - AL3320A_REG_CONFIG_RANGE, - FIELD_PREP(AL3320A_GAIN_MASK, i)); + return regmap_write(data->regmap, AL3320A_REG_CONFIG_RANGE, + FIELD_PREP(AL3320A_GAIN_MASK, i)); } break; } @@ -190,46 +196,50 @@ static const struct iio_info al3320a_info = { static int al3320a_probe(struct i2c_client *client) { struct al3320a_data *data; + struct device *dev = &client->dev; struct iio_dev *indio_dev; int ret; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); - data->client = client; + + data->regmap = devm_regmap_init_i2c(client, &al3320a_regmap_config); + if (IS_ERR(data->regmap)) + return dev_err_probe(dev, PTR_ERR(data->regmap), + "cannot allocate regmap\n"); indio_dev->info = &al3320a_info; - indio_dev->name = AL3320A_DRV_NAME; + indio_dev->name = "al3320a"; indio_dev->channels = al3320a_channels; indio_dev->num_channels = ARRAY_SIZE(al3320a_channels); indio_dev->modes = INDIO_DIRECT_MODE; ret = al3320a_init(data); if (ret < 0) { - dev_err(&client->dev, "al3320a chip init failed\n"); + dev_err(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); + return devm_iio_device_register(dev, indio_dev); } static int al3320a_suspend(struct device *dev) { - return al3320a_set_pwr(to_i2c_client(dev), false); + struct al3320a_data *data = iio_priv(dev_get_drvdata(dev)); + + al3320a_set_pwr_off(data); + return 0; } static int al3320a_resume(struct device *dev) { - return al3320a_set_pwr(to_i2c_client(dev), true); + struct al3320a_data *data = iio_priv(dev_get_drvdata(dev)); + + return al3320a_set_pwr_on(data); } static DEFINE_SIMPLE_DEV_PM_OPS(al3320a_pm_ops, al3320a_suspend, @@ -237,25 +247,25 @@ static DEFINE_SIMPLE_DEV_PM_OPS(al3320a_pm_ops, al3320a_suspend, static const struct i2c_device_id al3320a_id[] = { { "al3320a" }, - {} + { } }; 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 const struct acpi_device_id al3320a_acpi_match[] = { {"CALS0001"}, - { }, + { } }; MODULE_DEVICE_TABLE(acpi, al3320a_acpi_match); static struct i2c_driver al3320a_driver = { .driver = { - .name = AL3320A_DRV_NAME, + .name = "al3320a", .of_match_table = al3320a_of_match, .pm = pm_sleep_ptr(&al3320a_pm_ops), .acpi_match_table = al3320a_acpi_match, |