* [PATCH v2 1/3] iio: chemical: atlas-ph-sensor: reorg driver to allow multiple chips
2016-05-20 1:52 [PATCH v2 0/3] atlas-ph-sensor: add conductivity sensor support Matt Ranostay
@ 2016-05-20 1:52 ` Matt Ranostay
2016-05-20 1:53 ` [PATCH v2 2/3] iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type Matt Ranostay
2016-05-20 1:53 ` [PATCH v2 3/3] iio: chemical: atlas-ph-sensor: add EC feature Matt Ranostay
2 siblings, 0 replies; 7+ messages in thread
From: Matt Ranostay @ 2016-05-20 1:52 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Matt Ranostay
Signed-off-by: Matt Ranostay <mranostay@gmail.com>
---
drivers/iio/chemical/atlas-ph-sensor.c | 145 ++++++++++++++++++++-------------
1 file changed, 90 insertions(+), 55 deletions(-)
diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c
index 62b37cd..e85477c 100644
--- a/drivers/iio/chemical/atlas-ph-sensor.c
+++ b/drivers/iio/chemical/atlas-ph-sensor.c
@@ -24,6 +24,7 @@
#include <linux/irq_work.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
+#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
@@ -43,20 +44,25 @@
#define ATLAS_REG_PWR_CONTROL 0x06
-#define ATLAS_REG_CALIB_STATUS 0x0d
-#define ATLAS_REG_CALIB_STATUS_MASK 0x07
-#define ATLAS_REG_CALIB_STATUS_LOW BIT(0)
-#define ATLAS_REG_CALIB_STATUS_MID BIT(1)
-#define ATLAS_REG_CALIB_STATUS_HIGH BIT(2)
+#define ATLAS_REG_PH_CALIB_STATUS 0x0d
+#define ATLAS_REG_PH_CALIB_STATUS_MASK 0x07
+#define ATLAS_REG_PH_CALIB_STATUS_LOW BIT(0)
+#define ATLAS_REG_PH_CALIB_STATUS_MID BIT(1)
+#define ATLAS_REG_PH_CALIB_STATUS_HIGH BIT(2)
-#define ATLAS_REG_TEMP_DATA 0x0e
+#define ATLAS_REG_PH_TEMP_DATA 0x0e
#define ATLAS_REG_PH_DATA 0x16
#define ATLAS_PH_INT_TIME_IN_US 450000
+enum {
+ ATLAS_PH_SM,
+};
+
struct atlas_data {
struct i2c_client *client;
struct iio_trigger *trig;
+ struct atlas_device *chip;
struct regmap *regmap;
struct irq_work work;
@@ -84,9 +90,10 @@ static const struct regmap_config atlas_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static const struct iio_chan_spec atlas_channels[] = {
+static const struct iio_chan_spec atlas_ph_channels[] = {
{
.type = IIO_PH,
+ .address = ATLAS_REG_PH_DATA,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.scan_index = 0,
@@ -100,7 +107,7 @@ static const struct iio_chan_spec atlas_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(1),
{
.type = IIO_TEMP,
- .address = ATLAS_REG_TEMP_DATA,
+ .address = ATLAS_REG_PH_TEMP_DATA,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.output = 1,
@@ -108,6 +115,52 @@ static const struct iio_chan_spec atlas_channels[] = {
},
};
+static int atlas_check_ph_calibration(struct atlas_data *data)
+{
+ struct device *dev = &data->client->dev;
+ int ret;
+ unsigned int val;
+
+ ret = regmap_read(data->regmap, ATLAS_REG_PH_CALIB_STATUS, &val);
+ if (ret)
+ return ret;
+
+ if (!(val & ATLAS_REG_PH_CALIB_STATUS_MASK)) {
+ dev_warn(dev, "device has not been calibrated\n");
+ return 0;
+ }
+
+ if (!(val & ATLAS_REG_PH_CALIB_STATUS_LOW))
+ dev_warn(dev, "device missing low point calibration\n");
+
+ if (!(val & ATLAS_REG_PH_CALIB_STATUS_MID))
+ dev_warn(dev, "device missing mid point calibration\n");
+
+ if (!(val & ATLAS_REG_PH_CALIB_STATUS_HIGH))
+ dev_warn(dev, "device missing high point calibration\n");
+
+ return 0;
+}
+
+struct atlas_device {
+ const struct iio_chan_spec *channels;
+ int num_channels;
+ int data_reg;
+
+ int (*calibration)(struct atlas_data *data);
+ int delay;
+};
+
+static struct atlas_device atlas_devices[] = {
+ [ATLAS_PH_SM] = {
+ .channels = atlas_ph_channels,
+ .num_channels = 3,
+ .data_reg = ATLAS_REG_PH_DATA,
+ .calibration = &atlas_check_ph_calibration,
+ .delay = ATLAS_PH_INT_TIME_IN_US,
+ },
+};
+
static int atlas_set_powermode(struct atlas_data *data, int on)
{
return regmap_write(data->regmap, ATLAS_REG_PWR_CONTROL, on);
@@ -178,8 +231,9 @@ static irqreturn_t atlas_trigger_handler(int irq, void *private)
struct atlas_data *data = iio_priv(indio_dev);
int ret;
- ret = regmap_bulk_read(data->regmap, ATLAS_REG_PH_DATA,
- (u8 *) &data->buffer, sizeof(data->buffer[0]));
+ ret = regmap_bulk_read(data->regmap, data->chip->data_reg,
+ (u8 *) &data->buffer,
+ sizeof(__be32) * (data->chip->num_channels - 2));
if (!ret)
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
@@ -200,7 +254,7 @@ static irqreturn_t atlas_interrupt_handler(int irq, void *private)
return IRQ_HANDLED;
}
-static int atlas_read_ph_measurement(struct atlas_data *data, __be32 *val)
+static int atlas_read_measurement(struct atlas_data *data, int reg, __be32 *val)
{
struct device *dev = &data->client->dev;
int suspended = pm_runtime_suspended(dev);
@@ -213,11 +267,9 @@ static int atlas_read_ph_measurement(struct atlas_data *data, __be32 *val)
}
if (suspended)
- usleep_range(ATLAS_PH_INT_TIME_IN_US,
- ATLAS_PH_INT_TIME_IN_US + 100000);
+ usleep_range(data->chip->delay, data->chip->delay + 100000);
- ret = regmap_bulk_read(data->regmap, ATLAS_REG_PH_DATA,
- (u8 *) val, sizeof(*val));
+ ret = regmap_bulk_read(data->regmap, reg, (u8 *) val, sizeof(*val));
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
@@ -247,7 +299,8 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
if (iio_buffer_enabled(indio_dev))
ret = -EBUSY;
else
- ret = atlas_read_ph_measurement(data, ®);
+ ret = atlas_read_measurement(data,
+ chan->address, ®);
mutex_unlock(&indio_dev->mlock);
break;
@@ -303,37 +356,24 @@ static const struct iio_info atlas_info = {
.write_raw = atlas_write_raw,
};
-static int atlas_check_calibration(struct atlas_data *data)
-{
- struct device *dev = &data->client->dev;
- int ret;
- unsigned int val;
-
- ret = regmap_read(data->regmap, ATLAS_REG_CALIB_STATUS, &val);
- if (ret)
- return ret;
-
- if (!(val & ATLAS_REG_CALIB_STATUS_MASK)) {
- dev_warn(dev, "device has not been calibrated\n");
- return 0;
- }
-
- if (!(val & ATLAS_REG_CALIB_STATUS_LOW))
- dev_warn(dev, "device missing low point calibration\n");
-
- if (!(val & ATLAS_REG_CALIB_STATUS_MID))
- dev_warn(dev, "device missing mid point calibration\n");
-
- if (!(val & ATLAS_REG_CALIB_STATUS_HIGH))
- dev_warn(dev, "device missing high point calibration\n");
+static const struct i2c_device_id atlas_id[] = {
+ { "atlas-ph-sm", ATLAS_PH_SM},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, atlas_id);
- return 0;
+static const struct of_device_id atlas_dt_ids[] = {
+ { .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, },
+ { }
};
+MODULE_DEVICE_TABLE(of, atlas_dt_ids);
static int atlas_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct atlas_data *data;
+ struct atlas_device *chip;
+ const struct of_device_id *of_id;
struct iio_trigger *trig;
struct iio_dev *indio_dev;
int ret;
@@ -342,10 +382,16 @@ static int atlas_probe(struct i2c_client *client,
if (!indio_dev)
return -ENOMEM;
+ of_id = of_match_device(atlas_dt_ids, &client->dev);
+ if (!of_id)
+ chip = &atlas_devices[id->driver_data];
+ else
+ chip = &atlas_devices[(unsigned long)of_id->data];
+
indio_dev->info = &atlas_info;
indio_dev->name = ATLAS_DRV_NAME;
- indio_dev->channels = atlas_channels;
- indio_dev->num_channels = ARRAY_SIZE(atlas_channels);
+ indio_dev->channels = chip->channels;
+ indio_dev->num_channels = chip->num_channels;
indio_dev->modes = INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE;
indio_dev->dev.parent = &client->dev;
@@ -358,6 +404,7 @@ static int atlas_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
data->client = client;
data->trig = trig;
+ data->chip = chip;
trig->dev.parent = indio_dev->dev.parent;
trig->ops = &atlas_interrupt_trigger_ops;
iio_trigger_set_drvdata(trig, indio_dev);
@@ -379,7 +426,7 @@ static int atlas_probe(struct i2c_client *client,
return -EINVAL;
}
- ret = atlas_check_calibration(data);
+ ret = chip->calibration(data);
if (ret)
return ret;
@@ -480,18 +527,6 @@ static const struct dev_pm_ops atlas_pm_ops = {
atlas_runtime_resume, NULL)
};
-static const struct i2c_device_id atlas_id[] = {
- { "atlas-ph-sm", 0 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, atlas_id);
-
-static const struct of_device_id atlas_dt_ids[] = {
- { .compatible = "atlas,ph-sm" },
- { }
-};
-MODULE_DEVICE_TABLE(of, atlas_dt_ids);
-
static struct i2c_driver atlas_driver = {
.driver = {
.name = ATLAS_DRV_NAME,
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 2/3] iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type
2016-05-20 1:52 [PATCH v2 0/3] atlas-ph-sensor: add conductivity sensor support Matt Ranostay
2016-05-20 1:52 ` [PATCH v2 1/3] iio: chemical: atlas-ph-sensor: reorg driver to allow multiple chips Matt Ranostay
@ 2016-05-20 1:53 ` Matt Ranostay
2016-05-22 19:47 ` Jonathan Cameron
2016-05-20 1:53 ` [PATCH v2 3/3] iio: chemical: atlas-ph-sensor: add EC feature Matt Ranostay
2 siblings, 1 reply; 7+ messages in thread
From: Matt Ranostay @ 2016-05-20 1:53 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Matt Ranostay
Signed-off-by: Matt Ranostay <mranostay@gmail.com>
---
Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
drivers/iio/industrialio-core.c | 1 +
include/uapi/linux/iio/types.h | 1 +
3 files changed, 9 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index df44998..adfdf95 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1565,3 +1565,10 @@ Description:
* X is in the plane of the propellers, perpendicular to Y axis,
and positive towards the starboard side of the UAV ;
* Z is perpendicular to propellers plane and positive upwards.
+
+What: /sys/bus/iio/devices/iio:deviceX/in_electricalconductivity_raw
+KernelVersion: 4.8
+Contact: linux-iio@vger.kernel.org
+Description:
+ Raw (unscaled no offset etc.) electric conductivity reading that
+ maps to microsiemens per centimeter.
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index e6319a9..2a85bd8 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -80,6 +80,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_RESISTANCE] = "resistance",
[IIO_PH] = "ph",
[IIO_UVINDEX] = "uvindex",
+ [IIO_ELECTRICALCONDUCTIVITY] = "electricalconductivity",
};
static const char * const iio_modifier_names[] = {
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index b0916fc..22e5e58 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -39,6 +39,7 @@ enum iio_chan_type {
IIO_RESISTANCE,
IIO_PH,
IIO_UVINDEX,
+ IIO_ELECTRICALCONDUCTIVITY,
};
enum iio_modifier {
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/3] iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type
2016-05-20 1:53 ` [PATCH v2 2/3] iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type Matt Ranostay
@ 2016-05-22 19:47 ` Jonathan Cameron
2016-05-24 6:52 ` Matt Ranostay
0 siblings, 1 reply; 7+ messages in thread
From: Jonathan Cameron @ 2016-05-22 19:47 UTC (permalink / raw)
To: Matt Ranostay, linux-iio
On 20/05/16 02:53, Matt Ranostay wrote:
> Signed-off-by: Matt Ranostay <mranostay@gmail.com>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
> drivers/iio/industrialio-core.c | 1 +
> include/uapi/linux/iio/types.h | 1 +
> 3 files changed, 9 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index df44998..adfdf95 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1565,3 +1565,10 @@ Description:
> * X is in the plane of the propellers, perpendicular to Y axis,
> and positive towards the starboard side of the UAV ;
> * Z is perpendicular to propellers plane and positive upwards.
> +
> +What: /sys/bus/iio/devices/iio:deviceX/in_electricalconductivity_raw
> +KernelVersion: 4.8
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + Raw (unscaled no offset etc.) electric conductivity reading that
> + maps to microsiemens per centimeter.
Rather than seimens per m? Seems like the units are a mess when measuring this and
we do in theory aim for the basic SI units where possible...
Otherwise, this looks fine to me.
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index e6319a9..2a85bd8 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -80,6 +80,7 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_RESISTANCE] = "resistance",
> [IIO_PH] = "ph",
> [IIO_UVINDEX] = "uvindex",
> + [IIO_ELECTRICALCONDUCTIVITY] = "electricalconductivity",
> };
>
> static const char * const iio_modifier_names[] = {
> diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
> index b0916fc..22e5e58 100644
> --- a/include/uapi/linux/iio/types.h
> +++ b/include/uapi/linux/iio/types.h
> @@ -39,6 +39,7 @@ enum iio_chan_type {
> IIO_RESISTANCE,
> IIO_PH,
> IIO_UVINDEX,
> + IIO_ELECTRICALCONDUCTIVITY,
> };
>
> enum iio_modifier {
>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/3] iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type
2016-05-22 19:47 ` Jonathan Cameron
@ 2016-05-24 6:52 ` Matt Ranostay
2016-05-24 8:58 ` jic23
0 siblings, 1 reply; 7+ messages in thread
From: Matt Ranostay @ 2016-05-24 6:52 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio@vger.kernel.org
On Sun, May 22, 2016 at 12:47 PM, Jonathan Cameron <jic23@kernel.org> wrote:
> On 20/05/16 02:53, Matt Ranostay wrote:
>> Signed-off-by: Matt Ranostay <mranostay@gmail.com>
>> ---
>> Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
>> drivers/iio/industrialio-core.c | 1 +
>> include/uapi/linux/iio/types.h | 1 +
>> 3 files changed, 9 insertions(+)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
>> index df44998..adfdf95 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-iio
>> +++ b/Documentation/ABI/testing/sysfs-bus-iio
>> @@ -1565,3 +1565,10 @@ Description:
>> * X is in the plane of the propellers, perpendicular to Y axis,
>> and positive towards the starboard side of the UAV ;
>> * Z is perpendicular to propellers plane and positive upwards.
>> +
>> +What: /sys/bus/iio/devices/iio:deviceX/in_electricalconductivity_raw
>> +KernelVersion: 4.8
>> +Contact: linux-iio@vger.kernel.org
>> +Description:
>> + Raw (unscaled no offset etc.) electric conductivity reading that
>> + maps to microsiemens per centimeter.
> Rather than seimens per m? Seems like the units are a mess when measuring this and
> we do in theory aim for the basic SI units where possible...
>
Yeah seems most meters output this when they mean EC to be
microsiemens per cm....
I have no issue making this a siemens per meter and update the scaling
in the other patchset.
Thoughts?
> Otherwise, this looks fine to me.
>
>> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
>> index e6319a9..2a85bd8 100644
>> --- a/drivers/iio/industrialio-core.c
>> +++ b/drivers/iio/industrialio-core.c
>> @@ -80,6 +80,7 @@ static const char * const iio_chan_type_name_spec[] = {
>> [IIO_RESISTANCE] = "resistance",
>> [IIO_PH] = "ph",
>> [IIO_UVINDEX] = "uvindex",
>> + [IIO_ELECTRICALCONDUCTIVITY] = "electricalconductivity",
>> };
>>
>> static const char * const iio_modifier_names[] = {
>> diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
>> index b0916fc..22e5e58 100644
>> --- a/include/uapi/linux/iio/types.h
>> +++ b/include/uapi/linux/iio/types.h
>> @@ -39,6 +39,7 @@ enum iio_chan_type {
>> IIO_RESISTANCE,
>> IIO_PH,
>> IIO_UVINDEX,
>> + IIO_ELECTRICALCONDUCTIVITY,
>> };
>>
>> enum iio_modifier {
>>
>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/3] iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type
2016-05-24 6:52 ` Matt Ranostay
@ 2016-05-24 8:58 ` jic23
0 siblings, 0 replies; 7+ messages in thread
From: jic23 @ 2016-05-24 8:58 UTC (permalink / raw)
To: Matt Ranostay; +Cc: Jonathan Cameron, linux-iio
On 24.05.2016 07:52, Matt Ranostay wrote:
> On Sun, May 22, 2016 at 12:47 PM, Jonathan Cameron <jic23@kernel.org>
> wrote:
>> On 20/05/16 02:53, Matt Ranostay wrote:
>>> Signed-off-by: Matt Ranostay <mranostay@gmail.com>
>>> ---
>>> Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
>>> drivers/iio/industrialio-core.c | 1 +
>>> include/uapi/linux/iio/types.h | 1 +
>>> 3 files changed, 9 insertions(+)
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-bus-iio
>>> b/Documentation/ABI/testing/sysfs-bus-iio
>>> index df44998..adfdf95 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-iio
>>> +++ b/Documentation/ABI/testing/sysfs-bus-iio
>>> @@ -1565,3 +1565,10 @@ Description:
>>> * X is in the plane of the propellers, perpendicular to
>>> Y axis,
>>> and positive towards the starboard side of the UAV ;
>>> * Z is perpendicular to propellers plane and positive
>>> upwards.
>>> +
>>> +What:
>>> /sys/bus/iio/devices/iio:deviceX/in_electricalconductivity_raw
>>> +KernelVersion: 4.8
>>> +Contact: linux-iio@vger.kernel.org
>>> +Description:
>>> + Raw (unscaled no offset etc.) electric conductivity
>>> reading that
>>> + maps to microsiemens per centimeter.
>> Rather than seimens per m? Seems like the units are a mess when
>> measuring this and
>> we do in theory aim for the basic SI units where possible...
>>
>
> Yeah seems most meters output this when they mean EC to be
> microsiemens per cm....
> I have no issue making this a siemens per meter and update the scaling
> in the other patchset.
>
Update it. Just because the world is bonkers isn't a reason to follow
along :)
+ conversion is trivial anyway so I doubt anyone will moan about it.
J
> Thoughts?
>
>
>> Otherwise, this looks fine to me.
>>
>>> diff --git a/drivers/iio/industrialio-core.c
>>> b/drivers/iio/industrialio-core.c
>>> index e6319a9..2a85bd8 100644
>>> --- a/drivers/iio/industrialio-core.c
>>> +++ b/drivers/iio/industrialio-core.c
>>> @@ -80,6 +80,7 @@ static const char * const iio_chan_type_name_spec[]
>>> = {
>>> [IIO_RESISTANCE] = "resistance",
>>> [IIO_PH] = "ph",
>>> [IIO_UVINDEX] = "uvindex",
>>> + [IIO_ELECTRICALCONDUCTIVITY] = "electricalconductivity",
>>> };
>>>
>>> static const char * const iio_modifier_names[] = {
>>> diff --git a/include/uapi/linux/iio/types.h
>>> b/include/uapi/linux/iio/types.h
>>> index b0916fc..22e5e58 100644
>>> --- a/include/uapi/linux/iio/types.h
>>> +++ b/include/uapi/linux/iio/types.h
>>> @@ -39,6 +39,7 @@ enum iio_chan_type {
>>> IIO_RESISTANCE,
>>> IIO_PH,
>>> IIO_UVINDEX,
>>> + IIO_ELECTRICALCONDUCTIVITY,
>>> };
>>>
>>> enum iio_modifier {
>>>
>>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] iio: chemical: atlas-ph-sensor: add EC feature
2016-05-20 1:52 [PATCH v2 0/3] atlas-ph-sensor: add conductivity sensor support Matt Ranostay
2016-05-20 1:52 ` [PATCH v2 1/3] iio: chemical: atlas-ph-sensor: reorg driver to allow multiple chips Matt Ranostay
2016-05-20 1:53 ` [PATCH v2 2/3] iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type Matt Ranostay
@ 2016-05-20 1:53 ` Matt Ranostay
2 siblings, 0 replies; 7+ messages in thread
From: Matt Ranostay @ 2016-05-20 1:53 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Matt Ranostay
Signed-off-by: Matt Ranostay <mranostay@gmail.com>
---
.../bindings/iio/chemical/atlas,ec-sm.txt | 22 ++++
drivers/iio/chemical/Kconfig | 8 +-
drivers/iio/chemical/atlas-ph-sensor.c | 117 ++++++++++++++++++++-
3 files changed, 142 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt
diff --git a/Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt b/Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt
new file mode 100644
index 0000000..2962bd9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt
@@ -0,0 +1,22 @@
+* Atlas Scientific EC-SM OEM sensor
+
+http://www.atlas-scientific.com/_files/_datasheets/_oem/EC_oem_datasheet.pdf
+
+Required properties:
+
+ - compatible: must be "atlas,ec-sm"
+ - reg: the I2C address of the sensor
+ - interrupt-parent: should be the phandle for the interrupt controller
+ - interrupts: the sole interrupt generated by the device
+
+ Refer to interrupt-controller/interrupts.txt for generic interrupt client
+ node bindings.
+
+Example:
+
+atlas@64 {
+ compatible = "atlas,ec-sm";
+ reg = <0x64>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <16 2>;
+};
diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
index f73290f..4bcc025 100644
--- a/drivers/iio/chemical/Kconfig
+++ b/drivers/iio/chemical/Kconfig
@@ -5,15 +5,17 @@
menu "Chemical Sensors"
config ATLAS_PH_SENSOR
- tristate "Atlas Scientific OEM pH-SM sensor"
+ tristate "Atlas Scientific OEM SM sensors"
depends on I2C
select REGMAP_I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select IRQ_WORK
help
- Say Y here to build I2C interface support for the Atlas
- Scientific OEM pH-SM sensor.
+ Say Y here to build I2C interface support for the following
+ Atlas Scientific OEM SM sensors:
+ * pH SM sensor
+ * EC SM sensor
To compile this driver as module, choose M here: the
module will be called atlas-ph-sensor.
diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c
index e85477c..c0100eb 100644
--- a/drivers/iio/chemical/atlas-ph-sensor.c
+++ b/drivers/iio/chemical/atlas-ph-sensor.c
@@ -50,13 +50,28 @@
#define ATLAS_REG_PH_CALIB_STATUS_MID BIT(1)
#define ATLAS_REG_PH_CALIB_STATUS_HIGH BIT(2)
+#define ATLAS_REG_EC_CALIB_STATUS 0x0f
+#define ATLAS_REG_EC_CALIB_STATUS_MASK 0x0f
+#define ATLAS_REG_EC_CALIB_STATUS_DRY BIT(0)
+#define ATLAS_REG_EC_CALIB_STATUS_SINGLE BIT(1)
+#define ATLAS_REG_EC_CALIB_STATUS_LOW BIT(2)
+#define ATLAS_REG_EC_CALIB_STATUS_HIGH BIT(3)
+
#define ATLAS_REG_PH_TEMP_DATA 0x0e
#define ATLAS_REG_PH_DATA 0x16
+#define ATLAS_REG_EC_PROBE 0x08
+#define ATLAS_REG_EC_TEMP_DATA 0x10
+#define ATLAS_REG_EC_DATA 0x18
+#define ATLAS_REG_TDS_DATA 0x1c
+#define ATLAS_REG_PSS_DATA 0x20
+
#define ATLAS_PH_INT_TIME_IN_US 450000
+#define ATLAS_EC_INT_TIME_IN_US 650000
enum {
ATLAS_PH_SM,
+ ATLAS_EC_SM,
};
struct atlas_data {
@@ -66,12 +81,13 @@ struct atlas_data {
struct regmap *regmap;
struct irq_work work;
- __be32 buffer[4]; /* 32-bit pH data + 32-bit pad + 64-bit timestamp */
+ __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */
};
static const struct regmap_range atlas_volatile_ranges[] = {
regmap_reg_range(ATLAS_REG_INT_CONTROL, ATLAS_REG_INT_CONTROL),
regmap_reg_range(ATLAS_REG_PH_DATA, ATLAS_REG_PH_DATA + 4),
+ regmap_reg_range(ATLAS_REG_EC_DATA, ATLAS_REG_PSS_DATA + 4),
};
static const struct regmap_access_table atlas_volatile_table = {
@@ -86,7 +102,7 @@ static const struct regmap_config atlas_regmap_config = {
.val_bits = 8,
.volatile_table = &atlas_volatile_table,
- .max_register = ATLAS_REG_PH_DATA + 4,
+ .max_register = ATLAS_REG_PSS_DATA + 4,
.cache_type = REGCACHE_RBTREE,
};
@@ -115,6 +131,49 @@ static const struct iio_chan_spec atlas_ph_channels[] = {
},
};
+#define ATLAS_EC_CHANNEL(_idx, _addr) \
+ {\
+ .type = IIO_CONCENTRATION, \
+ .indexed = 1, \
+ .channel = _idx, \
+ .address = _addr, \
+ .info_mask_separate = \
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_index = _idx + 1, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 32, \
+ .storagebits = 32, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+static const struct iio_chan_spec atlas_ec_channels[] = {
+ {
+ .type = IIO_ELECTRICALCONDUCTIVITY,
+ .address = ATLAS_REG_EC_DATA,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 32,
+ .storagebits = 32,
+ .endianness = IIO_BE,
+ },
+ },
+ ATLAS_EC_CHANNEL(0, ATLAS_REG_TDS_DATA),
+ ATLAS_EC_CHANNEL(1, ATLAS_REG_PSS_DATA),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+ {
+ .type = IIO_TEMP,
+ .address = ATLAS_REG_EC_TEMP_DATA,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .output = 1,
+ .scan_index = -1
+ },
+};
+
static int atlas_check_ph_calibration(struct atlas_data *data)
{
struct device *dev = &data->client->dev;
@@ -142,6 +201,44 @@ static int atlas_check_ph_calibration(struct atlas_data *data)
return 0;
}
+static int atlas_check_ec_calibration(struct atlas_data *data)
+{
+ struct device *dev = &data->client->dev;
+ int ret;
+ unsigned int val;
+
+ ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &val, 2);
+ if (ret)
+ return ret;
+
+ dev_info(dev, "probe set to K = %d.%.2d", be16_to_cpu(val) / 100,
+ be16_to_cpu(val) % 100);
+
+ ret = regmap_read(data->regmap, ATLAS_REG_EC_CALIB_STATUS, &val);
+ if (ret)
+ return ret;
+
+ if (!(val & ATLAS_REG_EC_CALIB_STATUS_MASK)) {
+ dev_warn(dev, "device has not been calibrated\n");
+ return 0;
+ }
+
+ if (!(val & ATLAS_REG_EC_CALIB_STATUS_DRY))
+ dev_warn(dev, "device missing dry point calibration\n");
+
+ if (val & ATLAS_REG_EC_CALIB_STATUS_SINGLE) {
+ dev_warn(dev, "device using single point calibration\n");
+ } else {
+ if (!(val & ATLAS_REG_EC_CALIB_STATUS_LOW))
+ dev_warn(dev, "device missing low point calibration\n");
+
+ if (!(val & ATLAS_REG_EC_CALIB_STATUS_HIGH))
+ dev_warn(dev, "device missing high point calibration\n");
+ }
+
+ return 0;
+}
+
struct atlas_device {
const struct iio_chan_spec *channels;
int num_channels;
@@ -159,6 +256,14 @@ static struct atlas_device atlas_devices[] = {
.calibration = &atlas_check_ph_calibration,
.delay = ATLAS_PH_INT_TIME_IN_US,
},
+ [ATLAS_EC_SM] = {
+ .channels = atlas_ec_channels,
+ .num_channels = 5,
+ .data_reg = ATLAS_REG_EC_DATA,
+ .calibration = &atlas_check_ec_calibration,
+ .delay = ATLAS_EC_INT_TIME_IN_US,
+ },
+
};
static int atlas_set_powermode(struct atlas_data *data, int on)
@@ -294,6 +399,8 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
(u8 *) ®, sizeof(reg));
break;
case IIO_PH:
+ case IIO_CONCENTRATION:
+ case IIO_ELECTRICALCONDUCTIVITY:
mutex_lock(&indio_dev->mlock);
if (iio_buffer_enabled(indio_dev))
@@ -324,6 +431,10 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
*val = 1; /* 0.001 */
*val2 = 1000;
break;
+ case IIO_CONCENTRATION:
+ *val = 0; /* 0.000000001 */
+ *val2 = 1000;
+ return IIO_VAL_INT_PLUS_NANO;
default:
return -EINVAL;
}
@@ -358,12 +469,14 @@ static const struct iio_info atlas_info = {
static const struct i2c_device_id atlas_id[] = {
{ "atlas-ph-sm", ATLAS_PH_SM},
+ { "atlas-ec-sm", ATLAS_EC_SM},
{}
};
MODULE_DEVICE_TABLE(i2c, atlas_id);
static const struct of_device_id atlas_dt_ids[] = {
{ .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, },
+ { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, },
{ }
};
MODULE_DEVICE_TABLE(of, atlas_dt_ids);
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread