aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/chemical/atlas-ph-sensor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/chemical/atlas-ph-sensor.c')
-rw-r--r--drivers/iio/chemical/atlas-ph-sensor.c81
1 files changed, 57 insertions, 24 deletions
diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c
index 407f141a1eee..bd321b305a0a 100644
--- a/drivers/iio/chemical/atlas-ph-sensor.c
+++ b/drivers/iio/chemical/atlas-ph-sensor.c
@@ -66,12 +66,17 @@
66#define ATLAS_REG_TDS_DATA 0x1c 66#define ATLAS_REG_TDS_DATA 0x1c
67#define ATLAS_REG_PSS_DATA 0x20 67#define ATLAS_REG_PSS_DATA 0x20
68 68
69#define ATLAS_REG_ORP_CALIB_STATUS 0x0d
70#define ATLAS_REG_ORP_DATA 0x0e
71
69#define ATLAS_PH_INT_TIME_IN_US 450000 72#define ATLAS_PH_INT_TIME_IN_US 450000
70#define ATLAS_EC_INT_TIME_IN_US 650000 73#define ATLAS_EC_INT_TIME_IN_US 650000
74#define ATLAS_ORP_INT_TIME_IN_US 450000
71 75
72enum { 76enum {
73 ATLAS_PH_SM, 77 ATLAS_PH_SM,
74 ATLAS_EC_SM, 78 ATLAS_EC_SM,
79 ATLAS_ORP_SM,
75}; 80};
76 81
77struct atlas_data { 82struct atlas_data {
@@ -84,26 +89,10 @@ struct atlas_data {
84 __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */ 89 __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */
85}; 90};
86 91
87static const struct regmap_range atlas_volatile_ranges[] = {
88 regmap_reg_range(ATLAS_REG_INT_CONTROL, ATLAS_REG_INT_CONTROL),
89 regmap_reg_range(ATLAS_REG_PH_DATA, ATLAS_REG_PH_DATA + 4),
90 regmap_reg_range(ATLAS_REG_EC_DATA, ATLAS_REG_PSS_DATA + 4),
91};
92
93static const struct regmap_access_table atlas_volatile_table = {
94 .yes_ranges = atlas_volatile_ranges,
95 .n_yes_ranges = ARRAY_SIZE(atlas_volatile_ranges),
96};
97
98static const struct regmap_config atlas_regmap_config = { 92static const struct regmap_config atlas_regmap_config = {
99 .name = ATLAS_REGMAP_NAME, 93 .name = ATLAS_REGMAP_NAME,
100
101 .reg_bits = 8, 94 .reg_bits = 8,
102 .val_bits = 8, 95 .val_bits = 8,
103
104 .volatile_table = &atlas_volatile_table,
105 .max_register = ATLAS_REG_PSS_DATA + 4,
106 .cache_type = REGCACHE_RBTREE,
107}; 96};
108 97
109static const struct iio_chan_spec atlas_ph_channels[] = { 98static const struct iio_chan_spec atlas_ph_channels[] = {
@@ -175,6 +164,23 @@ static const struct iio_chan_spec atlas_ec_channels[] = {
175 }, 164 },
176}; 165};
177 166
167static const struct iio_chan_spec atlas_orp_channels[] = {
168 {
169 .type = IIO_VOLTAGE,
170 .address = ATLAS_REG_ORP_DATA,
171 .info_mask_separate =
172 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
173 .scan_index = 0,
174 .scan_type = {
175 .sign = 's',
176 .realbits = 32,
177 .storagebits = 32,
178 .endianness = IIO_BE,
179 },
180 },
181 IIO_CHAN_SOFT_TIMESTAMP(1),
182};
183
178static int atlas_check_ph_calibration(struct atlas_data *data) 184static int atlas_check_ph_calibration(struct atlas_data *data)
179{ 185{
180 struct device *dev = &data->client->dev; 186 struct device *dev = &data->client->dev;
@@ -240,6 +246,22 @@ static int atlas_check_ec_calibration(struct atlas_data *data)
240 return 0; 246 return 0;
241} 247}
242 248
249static int atlas_check_orp_calibration(struct atlas_data *data)
250{
251 struct device *dev = &data->client->dev;
252 int ret;
253 unsigned int val;
254
255 ret = regmap_read(data->regmap, ATLAS_REG_ORP_CALIB_STATUS, &val);
256 if (ret)
257 return ret;
258
259 if (!val)
260 dev_warn(dev, "device has not been calibrated\n");
261
262 return 0;
263};
264
243struct atlas_device { 265struct atlas_device {
244 const struct iio_chan_spec *channels; 266 const struct iio_chan_spec *channels;
245 int num_channels; 267 int num_channels;
@@ -264,7 +286,13 @@ static struct atlas_device atlas_devices[] = {
264 .calibration = &atlas_check_ec_calibration, 286 .calibration = &atlas_check_ec_calibration,
265 .delay = ATLAS_EC_INT_TIME_IN_US, 287 .delay = ATLAS_EC_INT_TIME_IN_US,
266 }, 288 },
267 289 [ATLAS_ORP_SM] = {
290 .channels = atlas_orp_channels,
291 .num_channels = 2,
292 .data_reg = ATLAS_REG_ORP_DATA,
293 .calibration = &atlas_check_orp_calibration,
294 .delay = ATLAS_ORP_INT_TIME_IN_US,
295 },
268}; 296};
269 297
270static int atlas_set_powermode(struct atlas_data *data, int on) 298static int atlas_set_powermode(struct atlas_data *data, int on)
@@ -402,15 +430,14 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
402 case IIO_PH: 430 case IIO_PH:
403 case IIO_CONCENTRATION: 431 case IIO_CONCENTRATION:
404 case IIO_ELECTRICALCONDUCTIVITY: 432 case IIO_ELECTRICALCONDUCTIVITY:
405 mutex_lock(&indio_dev->mlock); 433 case IIO_VOLTAGE:
434 ret = iio_device_claim_direct_mode(indio_dev);
435 if (ret)
436 return ret;
406 437
407 if (iio_buffer_enabled(indio_dev)) 438 ret = atlas_read_measurement(data, chan->address, &reg);
408 ret = -EBUSY;
409 else
410 ret = atlas_read_measurement(data,
411 chan->address, &reg);
412 439
413 mutex_unlock(&indio_dev->mlock); 440 iio_device_release_direct_mode(indio_dev);
414 break; 441 break;
415 default: 442 default:
416 ret = -EINVAL; 443 ret = -EINVAL;
@@ -440,6 +467,10 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
440 *val = 0; /* 0.000000001 */ 467 *val = 0; /* 0.000000001 */
441 *val2 = 1000; 468 *val2 = 1000;
442 return IIO_VAL_INT_PLUS_NANO; 469 return IIO_VAL_INT_PLUS_NANO;
470 case IIO_VOLTAGE:
471 *val = 1; /* 0.1 */
472 *val2 = 10;
473 break;
443 default: 474 default:
444 return -EINVAL; 475 return -EINVAL;
445 } 476 }
@@ -475,6 +506,7 @@ static const struct iio_info atlas_info = {
475static const struct i2c_device_id atlas_id[] = { 506static const struct i2c_device_id atlas_id[] = {
476 { "atlas-ph-sm", ATLAS_PH_SM}, 507 { "atlas-ph-sm", ATLAS_PH_SM},
477 { "atlas-ec-sm", ATLAS_EC_SM}, 508 { "atlas-ec-sm", ATLAS_EC_SM},
509 { "atlas-orp-sm", ATLAS_ORP_SM},
478 {} 510 {}
479}; 511};
480MODULE_DEVICE_TABLE(i2c, atlas_id); 512MODULE_DEVICE_TABLE(i2c, atlas_id);
@@ -482,6 +514,7 @@ MODULE_DEVICE_TABLE(i2c, atlas_id);
482static const struct of_device_id atlas_dt_ids[] = { 514static const struct of_device_id atlas_dt_ids[] = {
483 { .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, }, 515 { .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, },
484 { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, }, 516 { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, },
517 { .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, },
485 { } 518 { }
486}; 519};
487MODULE_DEVICE_TABLE(of, atlas_dt_ids); 520MODULE_DEVICE_TABLE(of, atlas_dt_ids);