|
|
@@ -98,6 +98,7 @@ struct ad5933_state {
|
|
|
struct i2c_client *client;
|
|
|
struct regulator *reg;
|
|
|
struct delayed_work work;
|
|
|
+ struct mutex lock; /* Protect sensor state */
|
|
|
unsigned long mclk_hz;
|
|
|
unsigned char ctrl_hb;
|
|
|
unsigned char ctrl_lb;
|
|
|
@@ -306,9 +307,11 @@ static ssize_t ad5933_show_frequency(struct device *dev,
|
|
|
u8 d8[4];
|
|
|
} dat;
|
|
|
|
|
|
- mutex_lock(&indio_dev->mlock);
|
|
|
+ ret = iio_device_claim_direct_mode(indio_dev);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
ret = ad5933_i2c_read(st->client, this_attr->address, 3, &dat.d8[1]);
|
|
|
- mutex_unlock(&indio_dev->mlock);
|
|
|
+ iio_device_release_direct_mode(indio_dev);
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
|
@@ -338,9 +341,11 @@ static ssize_t ad5933_store_frequency(struct device *dev,
|
|
|
if (val > AD5933_MAX_OUTPUT_FREQ_Hz)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- mutex_lock(&indio_dev->mlock);
|
|
|
+ ret = iio_device_claim_direct_mode(indio_dev);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
ret = ad5933_set_freq(st, this_attr->address, val);
|
|
|
- mutex_unlock(&indio_dev->mlock);
|
|
|
+ iio_device_release_direct_mode(indio_dev);
|
|
|
|
|
|
return ret ? ret : len;
|
|
|
}
|
|
|
@@ -364,7 +369,7 @@ static ssize_t ad5933_show(struct device *dev,
|
|
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
|
|
int ret = 0, len = 0;
|
|
|
|
|
|
- mutex_lock(&indio_dev->mlock);
|
|
|
+ mutex_lock(&st->lock);
|
|
|
switch ((u32)this_attr->address) {
|
|
|
case AD5933_OUT_RANGE:
|
|
|
len = sprintf(buf, "%u\n",
|
|
|
@@ -393,7 +398,7 @@ static ssize_t ad5933_show(struct device *dev,
|
|
|
ret = -EINVAL;
|
|
|
}
|
|
|
|
|
|
- mutex_unlock(&indio_dev->mlock);
|
|
|
+ mutex_unlock(&st->lock);
|
|
|
return ret ? ret : len;
|
|
|
}
|
|
|
|
|
|
@@ -415,7 +420,10 @@ static ssize_t ad5933_store(struct device *dev,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- mutex_lock(&indio_dev->mlock);
|
|
|
+ ret = iio_device_claim_direct_mode(indio_dev);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ mutex_lock(&st->lock);
|
|
|
switch ((u32)this_attr->address) {
|
|
|
case AD5933_OUT_RANGE:
|
|
|
ret = -EINVAL;
|
|
|
@@ -465,7 +473,8 @@ static ssize_t ad5933_store(struct device *dev,
|
|
|
ret = -EINVAL;
|
|
|
}
|
|
|
|
|
|
- mutex_unlock(&indio_dev->mlock);
|
|
|
+ mutex_unlock(&st->lock);
|
|
|
+ iio_device_release_direct_mode(indio_dev);
|
|
|
return ret ? ret : len;
|
|
|
}
|
|
|
|
|
|
@@ -532,11 +541,9 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
|
|
|
|
|
|
switch (m) {
|
|
|
case IIO_CHAN_INFO_RAW:
|
|
|
- mutex_lock(&indio_dev->mlock);
|
|
|
- if (iio_buffer_enabled(indio_dev)) {
|
|
|
- ret = -EBUSY;
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ ret = iio_device_claim_direct_mode(indio_dev);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
ret = ad5933_cmd(st, AD5933_CTRL_MEASURE_TEMP);
|
|
|
if (ret < 0)
|
|
|
goto out;
|
|
|
@@ -549,7 +556,7 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
|
|
|
2, (u8 *)&dat);
|
|
|
if (ret < 0)
|
|
|
goto out;
|
|
|
- mutex_unlock(&indio_dev->mlock);
|
|
|
+ iio_device_release_direct_mode(indio_dev);
|
|
|
*val = sign_extend32(be16_to_cpu(dat), 13);
|
|
|
|
|
|
return IIO_VAL_INT;
|
|
|
@@ -561,7 +568,7 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
|
|
|
|
|
|
return -EINVAL;
|
|
|
out:
|
|
|
- mutex_unlock(&indio_dev->mlock);
|
|
|
+ iio_device_release_direct_mode(indio_dev);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
@@ -657,18 +664,17 @@ static void ad5933_work(struct work_struct *work)
|
|
|
unsigned char status;
|
|
|
int ret;
|
|
|
|
|
|
- mutex_lock(&indio_dev->mlock);
|
|
|
if (st->state == AD5933_CTRL_INIT_START_FREQ) {
|
|
|
/* start sweep */
|
|
|
ad5933_cmd(st, AD5933_CTRL_START_SWEEP);
|
|
|
st->state = AD5933_CTRL_START_SWEEP;
|
|
|
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
|
|
- goto out;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
ret = ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status);
|
|
|
if (ret)
|
|
|
- goto out;
|
|
|
+ return;
|
|
|
|
|
|
if (status & AD5933_STAT_DATA_VALID) {
|
|
|
int scan_count = bitmap_weight(indio_dev->active_scan_mask,
|
|
|
@@ -678,7 +684,7 @@ static void ad5933_work(struct work_struct *work)
|
|
|
AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA,
|
|
|
scan_count * 2, (u8 *)buf);
|
|
|
if (ret)
|
|
|
- goto out;
|
|
|
+ return;
|
|
|
|
|
|
if (scan_count == 2) {
|
|
|
val[0] = be16_to_cpu(buf[0]);
|
|
|
@@ -690,7 +696,7 @@ static void ad5933_work(struct work_struct *work)
|
|
|
} else {
|
|
|
/* no data available - try again later */
|
|
|
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
|
|
- goto out;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
if (status & AD5933_STAT_SWEEP_DONE) {
|
|
|
@@ -703,8 +709,6 @@ static void ad5933_work(struct work_struct *work)
|
|
|
ad5933_cmd(st, AD5933_CTRL_INC_FREQ);
|
|
|
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
|
|
}
|
|
|
-out:
|
|
|
- mutex_unlock(&indio_dev->mlock);
|
|
|
}
|
|
|
|
|
|
static int ad5933_probe(struct i2c_client *client,
|
|
|
@@ -723,6 +727,8 @@ static int ad5933_probe(struct i2c_client *client,
|
|
|
i2c_set_clientdata(client, indio_dev);
|
|
|
st->client = client;
|
|
|
|
|
|
+ mutex_init(&st->lock);
|
|
|
+
|
|
|
if (!pdata)
|
|
|
pdata = &ad5933_default_pdata;
|
|
|
|