Commit eb3e6ae9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-3.13c' of...

Merge tag 'iio-for-3.13c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

Third set of new functionality and cleanups for IIO in the 3.13 cycle.

Driver New Functionality
* MXS - new interrupt driven touch screen support for i.MX23/28. Old
  polled implementation dropped.

Driver Cleanups
* Some spi_sync boilerplate dropped by using spi_sync_transfer
* Some switching of drivers to the fractional type for scale reading.
  Moves the ugly calculation into one place.
* Fix the documentation for *_voltage_scale which is never been correct
  or as implemented in any driver.
* HID sensor hub and children : Open the sensor hub only when someone cares.
* hmc5843 - various minor
parents 5f1a1369 3658a71b
...@@ -79,7 +79,7 @@ Description: ...@@ -79,7 +79,7 @@ Description:
correspond to externally available input one of the named correspond to externally available input one of the named
versions may be used. The number must always be specified and versions may be used. The number must always be specified and
unique to allow association with event codes. Units after unique to allow association with event codes. Units after
application of scale and offset are microvolts. application of scale and offset are millivolts.
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw
KernelVersion: 2.6.35 KernelVersion: 2.6.35
...@@ -90,7 +90,7 @@ Description: ...@@ -90,7 +90,7 @@ Description:
physically equivalent inputs when non differential readings are physically equivalent inputs when non differential readings are
separately available. In differential only parts, then all that separately available. In differential only parts, then all that
is required is a consistent labeling. Units after application is required is a consistent labeling. Units after application
of scale and offset are microvolts. of scale and offset are millivolts.
What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw
KernelVersion: 3.2 KernelVersion: 3.2
......
* Freescale i.MX28 LRADC device driver * Freescale i.MX28 LRADC device driver
Required properties: Required properties:
- compatible: Should be "fsl,imx28-lradc" - compatible: Should be "fsl,imx23-lradc" for i.MX23 SoC and "fsl,imx28-lradc"
for i.MX28 SoC
- reg: Address and length of the register set for the device - reg: Address and length of the register set for the device
- interrupts: Should contain the LRADC interrupts - interrupts: Should contain the LRADC interrupts
...@@ -9,13 +10,38 @@ Optional properties: ...@@ -9,13 +10,38 @@ Optional properties:
- fsl,lradc-touchscreen-wires: Number of wires used to connect the touchscreen - fsl,lradc-touchscreen-wires: Number of wires used to connect the touchscreen
to LRADC. Valid value is either 4 or 5. If this to LRADC. Valid value is either 4 or 5. If this
property is not present, then the touchscreen is property is not present, then the touchscreen is
disabled. disabled. 5 wires is valid for i.MX28 SoC only.
- fsl,ave-ctrl: number of samples per direction to calculate an average value.
Allowed value is 1 ... 31, default is 4
- fsl,ave-delay: delay between consecutive samples. Allowed value is
1 ... 2047. It is used if 'fsl,ave-ctrl' > 1, counts at
2 kHz and its default is 2 (= 1 ms)
- fsl,settling: delay between plate switch to next sample. Allowed value is
1 ... 2047. It counts at 2 kHz and its default is
10 (= 5 ms)
Examples: Example for i.MX23 SoC:
lradc@80050000 {
compatible = "fsl,imx23-lradc";
reg = <0x80050000 0x2000>;
interrupts = <36 37 38 39 40 41 42 43 44>;
status = "okay";
fsl,lradc-touchscreen-wires = <4>;
fsl,ave-ctrl = <4>;
fsl,ave-delay = <2>;
fsl,settling = <10>;
};
Example for i.MX28 SoC:
lradc@80050000 { lradc@80050000 {
compatible = "fsl,imx28-lradc"; compatible = "fsl,imx28-lradc";
reg = <0x80050000 0x2000>; reg = <0x80050000 0x2000>;
interrupts = <10 14 15 16 17 18 19 interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>;
20 21 22 23 24 25>; status = "okay";
fsl,lradc-touchscreen-wires = <5>;
fsl,ave-ctrl = <4>;
fsl,ave-delay = <2>;
fsl,settling = <10>;
}; };
...@@ -430,6 +430,7 @@ lradc@80050000 { ...@@ -430,6 +430,7 @@ lradc@80050000 {
reg = <0x80050000 0x2000>; reg = <0x80050000 0x2000>;
interrupts = <36 37 38 39 40 41 42 43 44>; interrupts = <36 37 38 39 40 41 42 43 44>;
status = "disabled"; status = "disabled";
clocks = <&clks 26>;
}; };
spdif@80054000 { spdif@80054000 {
......
...@@ -183,6 +183,10 @@ saif1: saif@80046000 { ...@@ -183,6 +183,10 @@ saif1: saif@80046000 {
lradc@80050000 { lradc@80050000 {
status = "okay"; status = "okay";
fsl,lradc-touchscreen-wires = <4>;
fsl,ave-ctrl = <4>;
fsl,ave-delay = <2>;
fsl,settling = <10>;
}; };
i2c0: i2c@80058000 { i2c0: i2c@80058000 {
......
...@@ -902,6 +902,7 @@ lradc: lradc@80050000 { ...@@ -902,6 +902,7 @@ lradc: lradc@80050000 {
interrupts = <10 14 15 16 17 18 19 interrupts = <10 14 15 16 17 18 19
20 21 22 23 24 25>; 20 21 22 23 24 25>;
status = "disabled"; status = "disabled";
clocks = <&clks 41>;
}; };
spdif: spdif@80054000 { spdif: spdif@80054000 {
......
...@@ -465,6 +465,39 @@ static int sensor_hub_raw_event(struct hid_device *hdev, ...@@ -465,6 +465,39 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
return 1; return 1;
} }
int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)
{
int ret = 0;
struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
mutex_lock(&data->mutex);
if (!hsdev->ref_cnt) {
ret = hid_hw_open(hsdev->hdev);
if (ret) {
hid_err(hsdev->hdev, "failed to open hid device\n");
mutex_unlock(&data->mutex);
return ret;
}
}
hsdev->ref_cnt++;
mutex_unlock(&data->mutex);
return ret;
}
EXPORT_SYMBOL_GPL(sensor_hub_device_open);
void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
{
struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
mutex_lock(&data->mutex);
hsdev->ref_cnt--;
if (!hsdev->ref_cnt)
hid_hw_close(hsdev->hdev);
mutex_unlock(&data->mutex);
}
EXPORT_SYMBOL_GPL(sensor_hub_device_close);
static int sensor_hub_probe(struct hid_device *hdev, static int sensor_hub_probe(struct hid_device *hdev,
const struct hid_device_id *id) const struct hid_device_id *id)
{ {
...@@ -506,12 +539,6 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -506,12 +539,6 @@ static int sensor_hub_probe(struct hid_device *hdev,
hid_err(hdev, "hw start failed\n"); hid_err(hdev, "hw start failed\n");
return ret; return ret;
} }
ret = hid_hw_open(hdev);
if (ret) {
hid_err(hdev, "failed to open input interrupt pipe\n");
goto err_stop_hw;
}
INIT_LIST_HEAD(&sd->dyn_callback_list); INIT_LIST_HEAD(&sd->dyn_callback_list);
sd->hid_sensor_client_cnt = 0; sd->hid_sensor_client_cnt = 0;
report_enum = &hdev->report_enum[HID_INPUT_REPORT]; report_enum = &hdev->report_enum[HID_INPUT_REPORT];
...@@ -520,7 +547,7 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -520,7 +547,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
if (dev_cnt > HID_MAX_PHY_DEVICES) { if (dev_cnt > HID_MAX_PHY_DEVICES) {
hid_err(hdev, "Invalid Physical device count\n"); hid_err(hdev, "Invalid Physical device count\n");
ret = -EINVAL; ret = -EINVAL;
goto err_close; goto err_stop_hw;
} }
sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt * sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt *
sizeof(struct mfd_cell), sizeof(struct mfd_cell),
...@@ -528,7 +555,7 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -528,7 +555,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
if (sd->hid_sensor_hub_client_devs == NULL) { if (sd->hid_sensor_hub_client_devs == NULL) {
hid_err(hdev, "Failed to allocate memory for mfd cells\n"); hid_err(hdev, "Failed to allocate memory for mfd cells\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err_close; goto err_stop_hw;
} }
list_for_each_entry(report, &report_enum->report_list, list) { list_for_each_entry(report, &report_enum->report_list, list) {
hid_dbg(hdev, "Report id:%x\n", report->id); hid_dbg(hdev, "Report id:%x\n", report->id);
...@@ -565,8 +592,6 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -565,8 +592,6 @@ static int sensor_hub_probe(struct hid_device *hdev,
for (i = 0; i < sd->hid_sensor_client_cnt ; ++i) for (i = 0; i < sd->hid_sensor_client_cnt ; ++i)
kfree(sd->hid_sensor_hub_client_devs[i].name); kfree(sd->hid_sensor_hub_client_devs[i].name);
kfree(sd->hid_sensor_hub_client_devs); kfree(sd->hid_sensor_hub_client_devs);
err_close:
hid_hw_close(hdev);
err_stop_hw: err_stop_hw:
hid_hw_stop(hdev); hid_hw_stop(hdev);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
struct ad7266_state { struct ad7266_state {
struct spi_device *spi; struct spi_device *spi;
struct regulator *reg; struct regulator *reg;
unsigned long vref_uv; unsigned long vref_mv;
struct spi_transfer single_xfer[3]; struct spi_transfer single_xfer[3];
struct spi_message single_msg; struct spi_message single_msg;
...@@ -156,7 +156,7 @@ static int ad7266_read_raw(struct iio_dev *indio_dev, ...@@ -156,7 +156,7 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long m) struct iio_chan_spec const *chan, int *val, int *val2, long m)
{ {
struct ad7266_state *st = iio_priv(indio_dev); struct ad7266_state *st = iio_priv(indio_dev);
unsigned long scale_uv; unsigned long scale_mv;
int ret; int ret;
switch (m) { switch (m) {
...@@ -174,16 +174,15 @@ static int ad7266_read_raw(struct iio_dev *indio_dev, ...@@ -174,16 +174,15 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->vref_uv * 100); scale_mv = st->vref_mv;
if (st->mode == AD7266_MODE_DIFF) if (st->mode == AD7266_MODE_DIFF)
scale_uv *= 2; scale_mv *= 2;
if (st->range == AD7266_RANGE_2VREF) if (st->range == AD7266_RANGE_2VREF)
scale_uv *= 2; scale_mv *= 2;
scale_uv >>= chan->scan_type.realbits; *val = scale_mv;
*val = scale_uv / 100000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 100000) * 10; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
if (st->range == AD7266_RANGE_2VREF && if (st->range == AD7266_RANGE_2VREF &&
st->mode != AD7266_MODE_DIFF) st->mode != AD7266_MODE_DIFF)
...@@ -414,10 +413,10 @@ static int ad7266_probe(struct spi_device *spi) ...@@ -414,10 +413,10 @@ static int ad7266_probe(struct spi_device *spi)
if (ret < 0) if (ret < 0)
goto error_disable_reg; goto error_disable_reg;
st->vref_uv = ret; st->vref_mv = ret / 1000;
} else { } else {
/* Use internal reference */ /* Use internal reference */
st->vref_uv = 2500000; st->vref_mv = 2500;
} }
if (pdata) { if (pdata) {
......
...@@ -127,10 +127,9 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, ...@@ -127,10 +127,9 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
} else { } else {
scale_uv = st->chip_info->int_vref_uv; scale_uv = st->chip_info->int_vref_uv;
} }
scale_uv >>= chan->scan_type.realbits; *val = scale_uv / 1000;
*val = scale_uv / 1000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -202,7 +202,6 @@ static int ad7791_read_raw(struct iio_dev *indio_dev, ...@@ -202,7 +202,6 @@ static int ad7791_read_raw(struct iio_dev *indio_dev,
{ {
struct ad7791_state *st = iio_priv(indio_dev); struct ad7791_state *st = iio_priv(indio_dev);
bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR); bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR);
unsigned long long scale_pv;
switch (info) { switch (info) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
...@@ -220,23 +219,26 @@ static int ad7791_read_raw(struct iio_dev *indio_dev, ...@@ -220,23 +219,26 @@ static int ad7791_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
/* The monitor channel uses an internal reference. */ /* The monitor channel uses an internal reference. */
if (chan->address == AD7791_CH_AVDD_MONITOR) { if (chan->address == AD7791_CH_AVDD_MONITOR) {
scale_pv = 5850000000000ULL; /*
* The signal is attenuated by a factor of 5 and
* compared against a 1.17V internal reference.
*/
*val = 1170 * 5;
} else { } else {
int voltage_uv; int voltage_uv;
voltage_uv = regulator_get_voltage(st->reg); voltage_uv = regulator_get_voltage(st->reg);
if (voltage_uv < 0) if (voltage_uv < 0)
return voltage_uv; return voltage_uv;
scale_pv = (unsigned long long)voltage_uv * 1000000;
*val = voltage_uv / 1000;
} }
if (unipolar) if (unipolar)
scale_pv >>= chan->scan_type.realbits; *val2 = chan->scan_type.realbits;
else else
scale_pv >>= chan->scan_type.realbits - 1; *val2 = chan->scan_type.realbits - 1;
*val2 = do_div(scale_pv, 1000000000);
*val = scale_pv;
return IIO_VAL_INT_PLUS_NANO; return IIO_VAL_FRACTIONAL_LOG2;
} }
return -EINVAL; return -EINVAL;
......
...@@ -366,9 +366,9 @@ static int at91_adc_read_raw(struct iio_dev *idev, ...@@ -366,9 +366,9 @@ static int at91_adc_read_raw(struct iio_dev *idev,
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = (st->vref_mv * 1000) >> chan->scan_type.realbits; *val = st->vref_mv;
*val2 = 0; *val2 = chan->scan_type.realbits;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_FRACTIONAL_LOG2;
default: default:
break; break;
} }
......
...@@ -397,7 +397,6 @@ static int max1363_read_raw(struct iio_dev *indio_dev, ...@@ -397,7 +397,6 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
{ {
struct max1363_state *st = iio_priv(indio_dev); struct max1363_state *st = iio_priv(indio_dev);
int ret; int ret;
unsigned long scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
...@@ -406,10 +405,9 @@ static int max1363_read_raw(struct iio_dev *indio_dev, ...@@ -406,10 +405,9 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
return ret; return ret;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = st->vref_uv >> st->chip_info->bits; *val = st->vref_uv / 1000;
*val = scale_uv / 1000; *val2 = st->chip_info->bits;
*val2 = (scale_uv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
default: default:
return -EINVAL; return -EINVAL;
} }
......
...@@ -34,6 +34,12 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig, ...@@ -34,6 +34,12 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
struct hid_sensor_common *st = iio_trigger_get_drvdata(trig); struct hid_sensor_common *st = iio_trigger_get_drvdata(trig);
int state_val; int state_val;
if (state) {
if (sensor_hub_device_open(st->hsdev))
return -EIO;
} else
sensor_hub_device_close(st->hsdev);
state_val = state ? 1 : 0; state_val = state ? 1 : 0;
if (IS_ENABLED(CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS)) if (IS_ENABLED(CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS))
++state_val; ++state_val;
......
...@@ -239,10 +239,9 @@ static int ad5064_read_raw(struct iio_dev *indio_dev, ...@@ -239,10 +239,9 @@ static int ad5064_read_raw(struct iio_dev *indio_dev,
if (scale_uv < 0) if (scale_uv < 0)
return scale_uv; return scale_uv;
scale_uv = (scale_uv * 100) >> chan->scan_type.realbits; *val = scale_uv / 1000;
*val = scale_uv / 100000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 100000) * 10; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
default: default:
break; break;
} }
......
...@@ -379,15 +379,14 @@ static int ad5360_read_raw(struct iio_dev *indio_dev, ...@@ -379,15 +379,14 @@ static int ad5360_read_raw(struct iio_dev *indio_dev,
*val = ret >> chan->scan_type.shift; *val = ret >> chan->scan_type.shift;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
/* vout = 4 * vref * dac_code */ scale_uv = ad5360_get_channel_vref(st, chan->channel);
scale_uv = ad5360_get_channel_vref(st, chan->channel) * 4 * 100;
if (scale_uv < 0) if (scale_uv < 0)
return scale_uv; return scale_uv;
scale_uv >>= (chan->scan_type.realbits); /* vout = 4 * vref * dac_code */
*val = scale_uv / 100000; *val = scale_uv * 4 / 1000;
*val2 = (scale_uv % 100000) * 10; *val2 = chan->scan_type.realbits;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET, ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
chan->address); chan->address);
......
...@@ -204,7 +204,6 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, ...@@ -204,7 +204,6 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long info) struct iio_chan_spec const *chan, int *val, int *val2, long info)
{ {
struct ad5380_state *st = iio_priv(indio_dev); struct ad5380_state *st = iio_priv(indio_dev);
unsigned long scale_uv;
int ret; int ret;
switch (info) { switch (info) {
...@@ -225,10 +224,9 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, ...@@ -225,10 +224,9 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
val -= (1 << chan->scan_type.realbits) / 2; val -= (1 << chan->scan_type.realbits) / 2;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = ((2 * st->vref) >> chan->scan_type.realbits) * 100; *val = 2 * st->vref;
*val = scale_uv / 100000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 100000) * 10; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
default: default:
break; break;
} }
...@@ -271,72 +269,72 @@ static const struct ad5380_chip_info ad5380_chip_info_tbl[] = { ...@@ -271,72 +269,72 @@ static const struct ad5380_chip_info ad5380_chip_info_tbl[] = {
[ID_AD5380_3] = { [ID_AD5380_3] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 40, .num_channels = 40,
.int_vref = 1250000, .int_vref = 1250,
}, },
[ID_AD5380_5] = { [ID_AD5380_5] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 40, .num_channels = 40,
.int_vref = 2500000, .int_vref = 2500,
}, },
[ID_AD5381_3] = { [ID_AD5381_3] = {
.channel_template = AD5380_CHANNEL(12), .channel_template = AD5380_CHANNEL(12),
.num_channels = 16, .num_channels = 16,
.int_vref = 1250000, .int_vref = 1250,
}, },
[ID_AD5381_5] = { [ID_AD5381_5] = {
.channel_template = AD5380_CHANNEL(12), .channel_template = AD5380_CHANNEL(12),
.num_channels = 16, .num_channels = 16,
.int_vref = 2500000, .int_vref = 2500,
}, },
[ID_AD5382_3] = { [ID_AD5382_3] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 32, .num_channels = 32,
.int_vref = 1250000, .int_vref = 1250,
}, },
[ID_AD5382_5] = { [ID_AD5382_5] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 32, .num_channels = 32,
.int_vref = 2500000, .int_vref = 2500,
}, },
[ID_AD5383_3] = { [ID_AD5383_3] = {
.channel_template = AD5380_CHANNEL(12), .channel_template = AD5380_CHANNEL(12),
.num_channels = 32, .num_channels = 32,
.int_vref = 1250000, .int_vref = 1250,
}, },
[ID_AD5383_5] = { [ID_AD5383_5] = {
.channel_template = AD5380_CHANNEL(12), .channel_template = AD5380_CHANNEL(12),
.num_channels = 32, .num_channels = 32,
.int_vref = 2500000, .int_vref = 2500,
}, },
[ID_AD5390_3] = { [ID_AD5390_3] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 16, .num_channels = 16,
.int_vref = 1250000, .int_vref = 1250,
}, },
[ID_AD5390_5] = { [ID_AD5390_5] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 16, .num_channels = 16,
.int_vref = 2500000, .int_vref = 2500,
}, },
[ID_AD5391_3] = { [ID_AD5391_3] = {
.channel_template = AD5380_CHANNEL(12), .channel_template = AD5380_CHANNEL(12),
.num_channels = 16, .num_channels = 16,
.int_vref = 1250000, .int_vref = 1250,
}, },
[ID_AD5391_5] = { [ID_AD5391_5] = {
.channel_template = AD5380_CHANNEL(12), .channel_template = AD5380_CHANNEL(12),
.num_channels = 16, .num_channels = 16,
.int_vref = 2500000, .int_vref = 2500,
}, },
[ID_AD5392_3] = { [ID_AD5392_3] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 8, .num_channels = 8,
.int_vref = 1250000, .int_vref = 1250,
}, },
[ID_AD5392_5] = { [ID_AD5392_5] = {
.channel_template = AD5380_CHANNEL(14), .channel_template = AD5380_CHANNEL(14),
.num_channels = 8, .num_channels = 8,
.int_vref = 2500000, .int_vref = 2500,
}, },
}; };
...@@ -395,7 +393,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap, ...@@ -395,7 +393,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
return ret; return ret;
} }
if (st->chip_info->int_vref == 2500000) if (st->chip_info->int_vref == 2500)
ctrl |= AD5380_CTRL_INT_VREF_2V5; ctrl |= AD5380_CTRL_INT_VREF_2V5;
st->vref_reg = devm_regulator_get(dev, "vref"); st->vref_reg = devm_regulator_get(dev, "vref");
...@@ -411,7 +409,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap, ...@@ -411,7 +409,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
if (ret < 0) if (ret < 0)
goto error_disable_reg; goto error_disable_reg;
st->vref = ret; st->vref = ret / 1000;
} else { } else {
st->vref = st->chip_info->int_vref; st->vref = st->chip_info->int_vref;
ctrl |= AD5380_CTRL_INT_VREF_EN; ctrl |= AD5380_CTRL_INT_VREF_EN;
......
...@@ -281,18 +281,11 @@ static inline unsigned int ad5421_get_offset(struct ad5421_state *st) ...@@ -281,18 +281,11 @@ static inline unsigned int ad5421_get_offset(struct ad5421_state *st)
return (min * (1 << 16)) / (max - min); return (min * (1 << 16)) / (max - min);
} }
static inline unsigned int ad5421_get_scale(struct ad5421_state *st)
{
unsigned int min, max;
ad5421_get_current_min_max(st, &min, &max);
return ((max - min) * 1000) / (1 << 16);
}
static int ad5421_read_raw(struct iio_dev *indio_dev, static int ad5421_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long m) struct iio_chan_spec const *chan, int *val, int *val2, long m)
{ {
struct ad5421_state *st = iio_priv(indio_dev); struct ad5421_state *st = iio_priv(indio_dev);
unsigned int min, max;
int ret; int ret;
if (chan->type != IIO_CURRENT) if (chan->type != IIO_CURRENT)
...@@ -306,9 +299,10 @@ static int ad5421_read_raw(struct iio_dev *indio_dev, ...@@ -306,9 +299,10 @@ static int ad5421_read_raw(struct iio_dev *indio_dev,
*val = ret; *val = ret;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = 0; ad5421_get_current_min_max(st, &min, &max);
*val2 = ad5421_get_scale(st); *val = max - min;
return IIO_VAL_INT_PLUS_MICRO; *val2 = (1 << 16) * 1000;
return IIO_VAL_FRACTIONAL;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
*val = ad5421_get_offset(st); *val = ad5421_get_offset(st);
return IIO_VAL_INT; return IIO_VAL_INT;
......
...@@ -163,18 +163,15 @@ static int ad5446_read_raw(struct iio_dev *indio_dev, ...@@ -163,18 +163,15 @@ static int ad5446_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct ad5446_state *st = iio_priv(indio_dev); struct ad5446_state *st = iio_priv(indio_dev);
unsigned long scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
*val = st->cached_val; *val = st->cached_val;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; *val = st->vref_mv;
*val = scale_uv / 1000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -101,7 +101,6 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr, ...@@ -101,7 +101,6 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
{ {
struct ad5449 *st = iio_priv(indio_dev); struct ad5449 *st = iio_priv(indio_dev);
int ret; int ret;
struct spi_message msg;
struct spi_transfer t[] = { struct spi_transfer t[] = {
{ {
.tx_buf = &st->data[0], .tx_buf = &st->data[0],
...@@ -114,15 +113,11 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr, ...@@ -114,15 +113,11 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
}, },
}; };
spi_message_init(&msg);
spi_message_add_tail(&t[0], &msg);
spi_message_add_tail(&t[1], &msg);
mutex_lock(&indio_dev->mlock); mutex_lock(&indio_dev->mlock);
st->data[0] = cpu_to_be16(addr << 12); st->data[0] = cpu_to_be16(addr << 12);
st->data[1] = cpu_to_be16(AD5449_CMD_NOOP); st->data[1] = cpu_to_be16(AD5449_CMD_NOOP);
ret = spi_sync(st->spi, &msg); ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
if (ret < 0) if (ret < 0)
goto out_unlock; goto out_unlock;
......
...@@ -100,7 +100,6 @@ static int ad5504_read_raw(struct iio_dev *indio_dev, ...@@ -100,7 +100,6 @@ static int ad5504_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct ad5504_state *st = iio_priv(indio_dev); struct ad5504_state *st = iio_priv(indio_dev);
unsigned long scale_uv;
int ret; int ret;
switch (m) { switch (m) {
...@@ -113,11 +112,9 @@ static int ad5504_read_raw(struct iio_dev *indio_dev, ...@@ -113,11 +112,9 @@ static int ad5504_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; *val = st->vref_mv;
*val = scale_uv / 1000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -50,15 +50,12 @@ static int ad5624r_read_raw(struct iio_dev *indio_dev, ...@@ -50,15 +50,12 @@ static int ad5624r_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct ad5624r_state *st = iio_priv(indio_dev); struct ad5624r_state *st = iio_priv(indio_dev);
unsigned long scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; *val = st->vref_mv;
*val = scale_uv / 1000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -201,7 +201,6 @@ static int ad5686_read_raw(struct iio_dev *indio_dev, ...@@ -201,7 +201,6 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct ad5686_state *st = iio_priv(indio_dev); struct ad5686_state *st = iio_priv(indio_dev);
unsigned long scale_uv;
int ret; int ret;
switch (m) { switch (m) {
...@@ -214,12 +213,9 @@ static int ad5686_read_raw(struct iio_dev *indio_dev, ...@@ -214,12 +213,9 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
*val = ret; *val = ret;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->vref_mv * 100000) *val = st->vref_mv;
>> (chan->scan_type.realbits); *val2 = chan->scan_type.realbits;
*val = scale_uv / 100000; return IIO_VAL_FRACTIONAL_LOG2;
*val2 = (scale_uv % 100000) * 10;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -253,15 +253,6 @@ static inline int ad5755_get_offset(struct ad5755_state *st, ...@@ -253,15 +253,6 @@ static inline int ad5755_get_offset(struct ad5755_state *st,
return (min * (1 << chan->scan_type.realbits)) / (max - min); return (min * (1 << chan->scan_type.realbits)) / (max - min);
} }
static inline int ad5755_get_scale(struct ad5755_state *st,
struct iio_chan_spec const *chan)
{
int min, max;
ad5755_get_min_max(st, chan, &min, &max);
return ((max - min) * 1000000000ULL) >> chan->scan_type.realbits;
}
static int ad5755_chan_reg_info(struct ad5755_state *st, static int ad5755_chan_reg_info(struct ad5755_state *st,
struct iio_chan_spec const *chan, long info, bool write, struct iio_chan_spec const *chan, long info, bool write,
unsigned int *reg, unsigned int *shift, unsigned int *offset) unsigned int *reg, unsigned int *shift, unsigned int *offset)
...@@ -303,13 +294,15 @@ static int ad5755_read_raw(struct iio_dev *indio_dev, ...@@ -303,13 +294,15 @@ static int ad5755_read_raw(struct iio_dev *indio_dev,
{ {
struct ad5755_state *st = iio_priv(indio_dev); struct ad5755_state *st = iio_priv(indio_dev);
unsigned int reg, shift, offset; unsigned int reg, shift, offset;
int min, max;
int ret; int ret;
switch (info) { switch (info) {
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = 0; ad5755_get_min_max(st, chan, &min, &max);
*val2 = ad5755_get_scale(st, chan); *val = max - min;
return IIO_VAL_INT_PLUS_NANO; *val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
*val = ad5755_get_offset(st, chan); *val = ad5755_get_offset(st, chan);
return IIO_VAL_INT; return IIO_VAL_INT;
......
...@@ -217,7 +217,6 @@ static int ad5764_read_raw(struct iio_dev *indio_dev, ...@@ -217,7 +217,6 @@ static int ad5764_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long info) struct iio_chan_spec const *chan, int *val, int *val2, long info)
{ {
struct ad5764_state *st = iio_priv(indio_dev); struct ad5764_state *st = iio_priv(indio_dev);
unsigned long scale_uv;
unsigned int reg; unsigned int reg;
int vref; int vref;
int ret; int ret;
...@@ -245,15 +244,14 @@ static int ad5764_read_raw(struct iio_dev *indio_dev, ...@@ -245,15 +244,14 @@ static int ad5764_read_raw(struct iio_dev *indio_dev,
*val = sign_extend32(*val, 5); *val = sign_extend32(*val, 5);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
/* vout = 4 * vref + ((dac_code / 65535) - 0.5) */ /* vout = 4 * vref + ((dac_code / 65536) - 0.5) */
vref = ad5764_get_channel_vref(st, chan->channel); vref = ad5764_get_channel_vref(st, chan->channel);
if (vref < 0) if (vref < 0)
return vref; return vref;
scale_uv = (vref * 4 * 100) >> chan->scan_type.realbits; *val = vref * 4 / 1000;
*val = scale_uv / 100000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 100000) * 10; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
*val = -(1 << chan->scan_type.realbits) / 2; *val = -(1 << chan->scan_type.realbits) / 2;
return IIO_VAL_INT; return IIO_VAL_INT;
......
...@@ -270,9 +270,9 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, ...@@ -270,9 +270,9 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
*val >>= chan->scan_type.shift; *val >>= chan->scan_type.shift;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = 0; *val = st->vref_mv;
*val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits; *val2 = (1 << chan->scan_type.realbits) - 1;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_FRACTIONAL;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits); val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
do_div(val64, st->vref_mv); do_div(val64, st->vref_mv);
......
...@@ -82,15 +82,13 @@ static int max517_read_raw(struct iio_dev *indio_dev, ...@@ -82,15 +82,13 @@ static int max517_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct max517_data *data = iio_priv(indio_dev); struct max517_data *data = iio_priv(indio_dev);
unsigned int scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
/* Corresponds to Vref / 2^(bits) */ /* Corresponds to Vref / 2^(bits) */
scale_uv = (data->vref_mv[chan->channel] * 1000) >> 8; *val = data->vref_mv[chan->channel];
*val = scale_uv / 1000000; *val2 = 8;
*val2 = scale_uv % 1000000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
default: default:
break; break;
} }
......
...@@ -239,17 +239,15 @@ static int mcp4725_read_raw(struct iio_dev *indio_dev, ...@@ -239,17 +239,15 @@ static int mcp4725_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask) int *val, int *val2, long mask)
{ {
struct mcp4725_data *data = iio_priv(indio_dev); struct mcp4725_data *data = iio_priv(indio_dev);
unsigned long scale_uv;
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
*val = data->dac_value; *val = data->dac_value;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (data->vref_mv * 1000) >> 12; *val = data->vref_mv;
*val = scale_uv / 1000000; *val2 = 12;
*val2 = scale_uv % 1000000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -51,7 +51,6 @@ static int adis16080_read_sample(struct iio_dev *indio_dev, ...@@ -51,7 +51,6 @@ static int adis16080_read_sample(struct iio_dev *indio_dev,
u16 addr, int *val) u16 addr, int *val)
{ {
struct adis16080_state *st = iio_priv(indio_dev); struct adis16080_state *st = iio_priv(indio_dev);
struct spi_message m;
int ret; int ret;
struct spi_transfer t[] = { struct spi_transfer t[] = {
{ {
...@@ -66,11 +65,7 @@ static int adis16080_read_sample(struct iio_dev *indio_dev, ...@@ -66,11 +65,7 @@ static int adis16080_read_sample(struct iio_dev *indio_dev,
st->buf = cpu_to_be16(addr | ADIS16080_DIN_WRITE); st->buf = cpu_to_be16(addr | ADIS16080_DIN_WRITE);
spi_message_init(&m); ret = spi_sync_transfer(st->us, t, ARRAY_SIZE(t));
spi_message_add_tail(&t[0], &m);
spi_message_add_tail(&t[1], &m);
ret = spi_sync(st->us, &m);
if (ret == 0) if (ret == 0)
*val = sign_extend32(be16_to_cpu(st->buf), 11); *val = sign_extend32(be16_to_cpu(st->buf), 11);
......
...@@ -47,7 +47,6 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val) ...@@ -47,7 +47,6 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
{ {
int ret; int ret;
struct adis16130_state *st = iio_priv(indio_dev); struct adis16130_state *st = iio_priv(indio_dev);
struct spi_message msg;
struct spi_transfer xfer = { struct spi_transfer xfer = {
.tx_buf = st->buf, .tx_buf = st->buf,
.rx_buf = st->buf, .rx_buf = st->buf,
...@@ -59,10 +58,7 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val) ...@@ -59,10 +58,7 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
st->buf[0] = ADIS16130_CON_RD | reg_addr; st->buf[0] = ADIS16130_CON_RD | reg_addr;
st->buf[1] = st->buf[2] = st->buf[3] = 0; st->buf[1] = st->buf[2] = st->buf[3] = 0;
spi_message_init(&msg); ret = spi_sync_transfer(st->us, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->us, &msg);
if (ret == 0) if (ret == 0)
*val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3]; *val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3];
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
......
...@@ -90,7 +90,6 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev, ...@@ -90,7 +90,6 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
u8 reg_address, u8 reg_address,
u16 *val) u16 *val)
{ {
struct spi_message msg;
struct adxrs450_state *st = iio_priv(indio_dev); struct adxrs450_state *st = iio_priv(indio_dev);
u32 tx; u32 tx;
int ret; int ret;
...@@ -114,10 +113,7 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev, ...@@ -114,10 +113,7 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
tx |= ADXRS450_P; tx |= ADXRS450_P;
st->tx = cpu_to_be32(tx); st->tx = cpu_to_be32(tx);
spi_message_init(&msg); ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
spi_message_add_tail(&xfers[0], &msg);
spi_message_add_tail(&xfers[1], &msg);
ret = spi_sync(st->us, &msg);
if (ret) { if (ret) {
dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n", dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
reg_address); reg_address);
...@@ -169,7 +165,6 @@ static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev, ...@@ -169,7 +165,6 @@ static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
**/ **/
static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val) static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
{ {
struct spi_message msg;
struct adxrs450_state *st = iio_priv(indio_dev); struct adxrs450_state *st = iio_priv(indio_dev);
int ret; int ret;
struct spi_transfer xfers[] = { struct spi_transfer xfers[] = {
...@@ -188,10 +183,7 @@ static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val) ...@@ -188,10 +183,7 @@ static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
mutex_lock(&st->buf_lock); mutex_lock(&st->buf_lock);
st->tx = cpu_to_be32(ADXRS450_SENSOR_DATA); st->tx = cpu_to_be32(ADXRS450_SENSOR_DATA);
spi_message_init(&msg); ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
spi_message_add_tail(&xfers[0], &msg);
spi_message_add_tail(&xfers[1], &msg);
ret = spi_sync(st->us, &msg);
if (ret) { if (ret) {
dev_err(&st->us->dev, "Problem while reading sensor data\n"); dev_err(&st->us->dev, "Problem while reading sensor data\n");
goto error_ret; goto error_ret;
......
...@@ -275,6 +275,12 @@ static int hid_time_probe(struct platform_device *pdev) ...@@ -275,6 +275,12 @@ static int hid_time_probe(struct platform_device *pdev)
return ret; return ret;
} }
ret = sensor_hub_device_open(hsdev);
if (ret) {
dev_err(&pdev->dev, "failed to open sensor hub device!\n");
goto err_open;
}
time_state->rtc = devm_rtc_device_register(&pdev->dev, time_state->rtc = devm_rtc_device_register(&pdev->dev,
"hid-sensor-time", &hid_time_rtc_ops, "hid-sensor-time", &hid_time_rtc_ops,
THIS_MODULE); THIS_MODULE);
...@@ -282,17 +288,24 @@ static int hid_time_probe(struct platform_device *pdev) ...@@ -282,17 +288,24 @@ static int hid_time_probe(struct platform_device *pdev)
if (IS_ERR_OR_NULL(time_state->rtc)) { if (IS_ERR_OR_NULL(time_state->rtc)) {
ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV; ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV;
time_state->rtc = NULL; time_state->rtc = NULL;
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
dev_err(&pdev->dev, "rtc device register failed!\n"); dev_err(&pdev->dev, "rtc device register failed!\n");
goto err_rtc;
} }
return ret; return ret;
err_rtc:
sensor_hub_device_close(hsdev);
err_open:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
return ret;
} }
static int hid_time_remove(struct platform_device *pdev) static int hid_time_remove(struct platform_device *pdev)
{ {
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
sensor_hub_device_close(hsdev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME); sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
return 0; return 0;
......
...@@ -13,6 +13,17 @@ Would be nice ...@@ -13,6 +13,17 @@ Would be nice
3) Expand device set. Lots of other maxim adc's have very 3) Expand device set. Lots of other maxim adc's have very
similar interfaces. similar interfaces.
MXS LRADC driver:
This is a classic MFD device as it combines the following subdevices
- touchscreen controller (input subsystem related device)
- general purpose ADC channels
- battery voltage monitor (power subsystem related device)
- die temperature monitor (thermal management)
At least the battery voltage and die temperature feature is required in-kernel
by a driver of the SoC's battery charging unit to avoid any damage to the
silicon and the battery.
TSL2561 TSL2561
Would be nice Would be nice
1) Open question of userspace vs kernel space balance when 1) Open question of userspace vs kernel space balance when
......
...@@ -102,7 +102,6 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, ...@@ -102,7 +102,6 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
int addr) int addr)
{ {
struct adis16220_state *st = iio_priv(indio_dev); struct adis16220_state *st = iio_priv(indio_dev);
struct spi_message msg;
struct spi_transfer xfers[] = { struct spi_transfer xfers[] = {
{ {
.tx_buf = st->tx, .tx_buf = st->tx,
...@@ -147,10 +146,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, ...@@ -147,10 +146,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
} }
xfers[1].len = count; xfers[1].len = count;
spi_message_init(&msg); ret = spi_sync_transfer(st->adis.spi, xfers, ARRAY_SIZE(xfers));
spi_message_add_tail(&xfers[0], &msg);
spi_message_add_tail(&xfers[1], &msg);
ret = spi_sync(st->adis.spi, &msg);
if (ret) { if (ret) {
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
......
...@@ -783,7 +783,6 @@ static int ad7280_read_raw(struct iio_dev *indio_dev, ...@@ -783,7 +783,6 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct ad7280_state *st = iio_priv(indio_dev); struct ad7280_state *st = iio_priv(indio_dev);
unsigned int scale_uv;
int ret; int ret;
switch (m) { switch (m) {
...@@ -804,13 +803,12 @@ static int ad7280_read_raw(struct iio_dev *indio_dev, ...@@ -804,13 +803,12 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6) if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6)
scale_uv = (4000 * 1000) >> AD7280A_BITS; *val = 4000;
else else
scale_uv = (5000 * 1000) >> AD7280A_BITS; *val = 5000;
*val = scale_uv / 1000; *val2 = AD7280A_BITS;
*val2 = (scale_uv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -85,7 +85,6 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, ...@@ -85,7 +85,6 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
{ {
int ret; int ret;
struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_state *st = iio_priv(indio_dev);
unsigned int scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
...@@ -101,11 +100,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, ...@@ -101,11 +100,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
*val = (short) ret; *val = (short) ret;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->range * 1000 * 2) *val = st->range * 2;
>> st->chip_info->channels[0].scan_type.realbits; *val2 = st->chip_info->channels[0].scan_type.realbits;
*val = scale_uv / 1000; return IIO_VAL_FRACTIONAL_LOG2;
*val2 = (scale_uv % 1000) * 1000;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -90,17 +90,14 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, ...@@ -90,17 +90,14 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct ad7780_state *st = iio_priv(indio_dev); struct ad7780_state *st = iio_priv(indio_dev);
unsigned long scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
return ad_sigma_delta_single_conversion(indio_dev, chan, val); return ad_sigma_delta_single_conversion(indio_dev, chan, val);
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->int_vref_mv * 100000 * st->gain) *val = st->int_vref_mv * st->gain;
>> (chan->scan_type.realbits - 1); *val2 = chan->scan_type.realbits - 1;
*val = scale_uv / 100000; return IIO_VAL_FRACTIONAL_LOG2;
*val2 = (scale_uv % 100000) * 10;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
*val -= (1 << (chan->scan_type.realbits - 1)); *val -= (1 << (chan->scan_type.realbits - 1));
return IIO_VAL_INT; return IIO_VAL_INT;
......
...@@ -163,7 +163,6 @@ static int ad799x_read_raw(struct iio_dev *indio_dev, ...@@ -163,7 +163,6 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
{ {
int ret; int ret;
struct ad799x_state *st = iio_priv(indio_dev); struct ad799x_state *st = iio_priv(indio_dev);
unsigned int scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
...@@ -180,10 +179,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev, ...@@ -180,10 +179,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
RES_MASK(chan->scan_type.realbits); RES_MASK(chan->scan_type.realbits);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->int_vref_mv * 1000) >> chan->scan_type.realbits; *val = st->int_vref_mv;
*val = scale_uv / 1000; *val2 = chan->scan_type.realbits;
*val2 = (scale_uv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/clk.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/buffer.h> #include <linux/iio/buffer.h>
...@@ -129,11 +130,24 @@ enum mxs_lradc_ts { ...@@ -129,11 +130,24 @@ enum mxs_lradc_ts {
MXS_LRADC_TOUCHSCREEN_5WIRE, MXS_LRADC_TOUCHSCREEN_5WIRE,
}; };
/*
* Touchscreen handling
*/
enum lradc_ts_plate {
LRADC_TOUCH = 0,
LRADC_SAMPLE_X,
LRADC_SAMPLE_Y,
LRADC_SAMPLE_PRESSURE,
LRADC_SAMPLE_VALID,
};
struct mxs_lradc { struct mxs_lradc {
struct device *dev; struct device *dev;
void __iomem *base; void __iomem *base;
int irq[13]; int irq[13];
struct clk *clk;
uint32_t *buffer; uint32_t *buffer;
struct iio_trigger *trig; struct iio_trigger *trig;
...@@ -169,32 +183,63 @@ struct mxs_lradc { ...@@ -169,32 +183,63 @@ struct mxs_lradc {
#define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 2) #define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 2)
#define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 2) #define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 2)
enum mxs_lradc_ts use_touchscreen; enum mxs_lradc_ts use_touchscreen;
bool stop_touchscreen;
bool use_touchbutton; bool use_touchbutton;
struct input_dev *ts_input; struct input_dev *ts_input;
struct work_struct ts_work;
enum mxs_lradc_id soc;
enum lradc_ts_plate cur_plate; /* statemachine */
bool ts_valid;
unsigned ts_x_pos;
unsigned ts_y_pos;
unsigned ts_pressure;
/* handle touchscreen's physical behaviour */
/* samples per coordinate */
unsigned over_sample_cnt;
/* time clocks between samples */
unsigned over_sample_delay;
/* time in clocks to wait after the plates where switched */
unsigned settling_delay;
}; };
#define LRADC_CTRL0 0x00 #define LRADC_CTRL0 0x00
#define LRADC_CTRL0_TOUCH_DETECT_ENABLE (1 << 23) # define LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE (1 << 23)
#define LRADC_CTRL0_TOUCH_SCREEN_TYPE (1 << 22) # define LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE (1 << 22)
#define LRADC_CTRL0_YNNSW /* YM */ (1 << 21) # define LRADC_CTRL0_MX28_YNNSW /* YM */ (1 << 21)
#define LRADC_CTRL0_YPNSW /* YP */ (1 << 20) # define LRADC_CTRL0_MX28_YPNSW /* YP */ (1 << 20)
#define LRADC_CTRL0_YPPSW /* YP */ (1 << 19) # define LRADC_CTRL0_MX28_YPPSW /* YP */ (1 << 19)
#define LRADC_CTRL0_XNNSW /* XM */ (1 << 18) # define LRADC_CTRL0_MX28_XNNSW /* XM */ (1 << 18)
#define LRADC_CTRL0_XNPSW /* XM */ (1 << 17) # define LRADC_CTRL0_MX28_XNPSW /* XM */ (1 << 17)
#define LRADC_CTRL0_XPPSW /* XP */ (1 << 16) # define LRADC_CTRL0_MX28_XPPSW /* XP */ (1 << 16)
#define LRADC_CTRL0_PLATE_MASK (0x3f << 16)
# define LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE (1 << 20)
# define LRADC_CTRL0_MX23_YM (1 << 19)
# define LRADC_CTRL0_MX23_XM (1 << 18)
# define LRADC_CTRL0_MX23_YP (1 << 17)
# define LRADC_CTRL0_MX23_XP (1 << 16)
# define LRADC_CTRL0_MX28_PLATE_MASK \
(LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE | \
LRADC_CTRL0_MX28_YNNSW | LRADC_CTRL0_MX28_YPNSW | \
LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW | \
LRADC_CTRL0_MX28_XNPSW | LRADC_CTRL0_MX28_XPPSW)
# define LRADC_CTRL0_MX23_PLATE_MASK \
(LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE | \
LRADC_CTRL0_MX23_YM | LRADC_CTRL0_MX23_XM | \
LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XP)
#define LRADC_CTRL1 0x10 #define LRADC_CTRL1 0x10
#define LRADC_CTRL1_TOUCH_DETECT_IRQ_EN (1 << 24) #define LRADC_CTRL1_TOUCH_DETECT_IRQ_EN (1 << 24)
#define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16)) #define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16))
#define LRADC_CTRL1_LRADC_IRQ_EN_MASK (0x1fff << 16) #define LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK (0x1fff << 16)
#define LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK (0x01ff << 16)
#define LRADC_CTRL1_LRADC_IRQ_EN_OFFSET 16 #define LRADC_CTRL1_LRADC_IRQ_EN_OFFSET 16
#define LRADC_CTRL1_TOUCH_DETECT_IRQ (1 << 8) #define LRADC_CTRL1_TOUCH_DETECT_IRQ (1 << 8)
#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n)) #define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n))
#define LRADC_CTRL1_LRADC_IRQ_MASK 0x1fff #define LRADC_CTRL1_MX28_LRADC_IRQ_MASK 0x1fff
#define LRADC_CTRL1_MX23_LRADC_IRQ_MASK 0x01ff
#define LRADC_CTRL1_LRADC_IRQ_OFFSET 0 #define LRADC_CTRL1_LRADC_IRQ_OFFSET 0
#define LRADC_CTRL2 0x20 #define LRADC_CTRL2 0x20
...@@ -207,19 +252,33 @@ struct mxs_lradc { ...@@ -207,19 +252,33 @@ struct mxs_lradc {
#define LRADC_CH_ACCUMULATE (1 << 29) #define LRADC_CH_ACCUMULATE (1 << 29)
#define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24) #define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24)
#define LRADC_CH_NUM_SAMPLES_OFFSET 24 #define LRADC_CH_NUM_SAMPLES_OFFSET 24
#define LRADC_CH_NUM_SAMPLES(x) \
((x) << LRADC_CH_NUM_SAMPLES_OFFSET)
#define LRADC_CH_VALUE_MASK 0x3ffff #define LRADC_CH_VALUE_MASK 0x3ffff
#define LRADC_CH_VALUE_OFFSET 0 #define LRADC_CH_VALUE_OFFSET 0
#define LRADC_DELAY(n) (0xd0 + (0x10 * (n))) #define LRADC_DELAY(n) (0xd0 + (0x10 * (n)))
#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24) #define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24)
#define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24 #define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24
#define LRADC_DELAY_TRIGGER(x) \
(((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \
LRADC_DELAY_TRIGGER_LRADCS_MASK)
#define LRADC_DELAY_KICK (1 << 20) #define LRADC_DELAY_KICK (1 << 20)
#define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16) #define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16)
#define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16 #define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16
#define LRADC_DELAY_TRIGGER_DELAYS(x) \
(((x) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) & \
LRADC_DELAY_TRIGGER_DELAYS_MASK)
#define LRADC_DELAY_LOOP_COUNT_MASK (0x1f << 11) #define LRADC_DELAY_LOOP_COUNT_MASK (0x1f << 11)
#define LRADC_DELAY_LOOP_COUNT_OFFSET 11 #define LRADC_DELAY_LOOP_COUNT_OFFSET 11
#define LRADC_DELAY_LOOP(x) \
(((x) << LRADC_DELAY_LOOP_COUNT_OFFSET) & \
LRADC_DELAY_LOOP_COUNT_MASK)
#define LRADC_DELAY_DELAY_MASK 0x7ff #define LRADC_DELAY_DELAY_MASK 0x7ff
#define LRADC_DELAY_DELAY_OFFSET 0 #define LRADC_DELAY_DELAY_OFFSET 0
#define LRADC_DELAY_DELAY(x) \
(((x) << LRADC_DELAY_DELAY_OFFSET) & \
LRADC_DELAY_DELAY_MASK)
#define LRADC_CTRL4 0x140 #define LRADC_CTRL4 0x140
#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4)) #define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4))
...@@ -228,6 +287,475 @@ struct mxs_lradc { ...@@ -228,6 +287,475 @@ struct mxs_lradc {
#define LRADC_RESOLUTION 12 #define LRADC_RESOLUTION 12
#define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1) #define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1)
static void mxs_lradc_reg_set(struct mxs_lradc *lradc, u32 val, u32 reg)
{
writel(val, lradc->base + reg + STMP_OFFSET_REG_SET);
}
static void mxs_lradc_reg_clear(struct mxs_lradc *lradc, u32 val, u32 reg)
{
writel(val, lradc->base + reg + STMP_OFFSET_REG_CLR);
}
static void mxs_lradc_reg_wrt(struct mxs_lradc *lradc, u32 val, u32 reg)
{
writel(val, lradc->base + reg);
}
static u32 mxs_lradc_plate_mask(struct mxs_lradc *lradc)
{
if (lradc->soc == IMX23_LRADC)
return LRADC_CTRL0_MX23_PLATE_MASK;
else
return LRADC_CTRL0_MX28_PLATE_MASK;
}
static u32 mxs_lradc_irq_en_mask(struct mxs_lradc *lradc)
{
if (lradc->soc == IMX23_LRADC)
return LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK;
else
return LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK;
}
static u32 mxs_lradc_irq_mask(struct mxs_lradc *lradc)
{
if (lradc->soc == IMX23_LRADC)
return LRADC_CTRL1_MX23_LRADC_IRQ_MASK;
else
return LRADC_CTRL1_MX28_LRADC_IRQ_MASK;
}
static u32 mxs_lradc_touch_detect_bit(struct mxs_lradc *lradc)
{
if (lradc->soc == IMX23_LRADC)
return LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE;
else
return LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE;
}
static u32 mxs_lradc_drive_x_plate(struct mxs_lradc *lradc)
{
if (lradc->soc == IMX23_LRADC)
return LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM;
else
return LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW;
}
static u32 mxs_lradc_drive_y_plate(struct mxs_lradc *lradc)
{
if (lradc->soc == IMX23_LRADC)
return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM;
else
return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW;
}
static u32 mxs_lradc_drive_pressure(struct mxs_lradc *lradc)
{
if (lradc->soc == IMX23_LRADC)
return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM;
else
return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW;
}
static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
{
return !!(readl(lradc->base + LRADC_STATUS) &
LRADC_STATUS_TOUCH_DETECT_RAW);
}
static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
{
/*
* prepare for oversampling conversion
*
* from the datasheet:
* "The ACCUMULATE bit in the appropriate channel register
* HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
* otherwise, the IRQs will not fire."
*/
mxs_lradc_reg_wrt(lradc, LRADC_CH_ACCUMULATE |
LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1),
LRADC_CH(ch));
/* from the datasheet:
* "Software must clear this register in preparation for a
* multi-cycle accumulation.
*/
mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
/* prepare the delay/loop unit according to the oversampling count */
mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
LRADC_DELAY_TRIGGER_DELAYS(0) |
LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
LRADC_DELAY(3));
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
/* wake us again, when the complete conversion is done */
mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1);
/*
* after changing the touchscreen plates setting
* the signals need some initial time to settle. Start the
* SoC's delay unit and start the conversion later
* and automatically.
*/
mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
LRADC_DELAY_KICK |
LRADC_DELAY_DELAY(lradc->settling_delay),
LRADC_DELAY(2));
}
/*
* Pressure detection is special:
* We want to do both required measurements for the pressure detection in
* one turn. Use the hardware features to chain both conversions and let the
* hardware report one interrupt if both conversions are done
*/
static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1,
unsigned ch2)
{
u32 reg;
/*
* prepare for oversampling conversion
*
* from the datasheet:
* "The ACCUMULATE bit in the appropriate channel register
* HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
* otherwise, the IRQs will not fire."
*/
reg = LRADC_CH_ACCUMULATE |
LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1);
mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch1));
mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch2));
/* from the datasheet:
* "Software must clear this register in preparation for a
* multi-cycle accumulation.
*/
mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch1));
mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch2));
/* prepare the delay/loop unit according to the oversampling count */
mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch1) |
LRADC_DELAY_TRIGGER(1 << ch2) | /* start both channels */
LRADC_DELAY_TRIGGER_DELAYS(0) |
LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
LRADC_DELAY(3));
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
/* wake us again, when the conversions are done */
mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1);
/*
* after changing the touchscreen plates setting
* the signals need some initial time to settle. Start the
* SoC's delay unit and start the conversion later
* and automatically.
*/
mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
LRADC_DELAY_KICK |
LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2));
}
static unsigned mxs_lradc_read_raw_channel(struct mxs_lradc *lradc,
unsigned channel)
{
u32 reg;
unsigned num_samples, val;
reg = readl(lradc->base + LRADC_CH(channel));
if (reg & LRADC_CH_ACCUMULATE)
num_samples = lradc->over_sample_cnt;
else
num_samples = 1;
val = (reg & LRADC_CH_VALUE_MASK) >> LRADC_CH_VALUE_OFFSET;
return val / num_samples;
}
static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc,
unsigned ch1, unsigned ch2)
{
u32 reg, mask;
unsigned pressure, m1, m2;
mask = LRADC_CTRL1_LRADC_IRQ(ch1) | LRADC_CTRL1_LRADC_IRQ(ch2);
reg = readl(lradc->base + LRADC_CTRL1) & mask;
while (reg != mask) {
reg = readl(lradc->base + LRADC_CTRL1) & mask;
dev_dbg(lradc->dev, "One channel is still busy: %X\n", reg);
}
m1 = mxs_lradc_read_raw_channel(lradc, ch1);
m2 = mxs_lradc_read_raw_channel(lradc, ch2);
if (m2 == 0) {
dev_warn(lradc->dev, "Cannot calculate pressure\n");
return 1 << (LRADC_RESOLUTION - 1);
}
/* simply scale the value from 0 ... max ADC resolution */
pressure = m1;
pressure *= (1 << LRADC_RESOLUTION);
pressure /= m2;
dev_dbg(lradc->dev, "Pressure = %u\n", pressure);
return pressure;
}
#define TS_CH_XP 2
#define TS_CH_YP 3
#define TS_CH_XM 4
#define TS_CH_YM 5
static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc)
{
u32 reg;
int val;
reg = readl(lradc->base + LRADC_CTRL1);
/* only channels 3 to 5 are of interest here */
if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) {
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) |
LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1);
val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP);
} else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) {
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) |
LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1);
val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM);
} else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) {
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) |
LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1);
val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM);
} else {
return -EIO;
}
mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
return val;
}
/*
* YP(open)--+-------------+
* | |--+
* | | |
* YM(-)--+-------------+ |
* +--------------+
* | |
* XP(weak+) XM(open)
*
* "weak+" means 200k Ohm VDDIO
* (-) means GND
*/
static void mxs_lradc_setup_touch_detection(struct mxs_lradc *lradc)
{
/*
* In order to detect a touch event the 'touch detect enable' bit
* enables:
* - a weak pullup to the X+ connector
* - a strong ground at the Y- connector
*/
mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
mxs_lradc_reg_set(lradc, mxs_lradc_touch_detect_bit(lradc),
LRADC_CTRL0);
}
/*
* YP(meas)--+-------------+
* | |--+
* | | |
* YM(open)--+-------------+ |
* +--------------+
* | |
* XP(+) XM(-)
*
* (+) means here 1.85 V
* (-) means here GND
*/
static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
{
mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
lradc->cur_plate = LRADC_SAMPLE_X;
mxs_lradc_setup_ts_channel(lradc, TS_CH_YP);
}
/*
* YP(+)--+-------------+
* | |--+
* | | |
* YM(-)--+-------------+ |
* +--------------+
* | |
* XP(open) XM(meas)
*
* (+) means here 1.85 V
* (-) means here GND
*/
static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
{
mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
lradc->cur_plate = LRADC_SAMPLE_Y;
mxs_lradc_setup_ts_channel(lradc, TS_CH_XM);
}
/*
* YP(+)--+-------------+
* | |--+
* | | |
* YM(meas)--+-------------+ |
* +--------------+
* | |
* XP(meas) XM(-)
*
* (+) means here 1.85 V
* (-) means here GND
*/
static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
{
mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
}
static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
{
mxs_lradc_setup_touch_detection(lradc);
lradc->cur_plate = LRADC_TOUCH;
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ |
LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
}
static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc)
{
input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos);
input_report_abs(lradc->ts_input, ABS_Y, lradc->ts_y_pos);
input_report_abs(lradc->ts_input, ABS_PRESSURE, lradc->ts_pressure);
input_report_key(lradc->ts_input, BTN_TOUCH, 1);
input_sync(lradc->ts_input);
}
static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc)
{
mxs_lradc_setup_touch_detection(lradc);
lradc->cur_plate = LRADC_SAMPLE_VALID;
/*
* start a dummy conversion to burn time to settle the signals
* note: we are not interested in the conversion's value
*/
mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(5));
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(5), LRADC_CTRL1);
mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << 5) |
LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */
LRADC_DELAY(2));
}
/*
* in order to avoid false measurements, report only samples where
* the surface is still touched after the position measurement
*/
static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid)
{
/* if it is still touched, report the sample */
if (valid && mxs_lradc_check_touch_event(lradc)) {
lradc->ts_valid = true;
mxs_lradc_report_ts_event(lradc);
}
/* if it is even still touched, continue with the next measurement */
if (mxs_lradc_check_touch_event(lradc)) {
mxs_lradc_prepare_y_pos(lradc);
return;
}
if (lradc->ts_valid) {
/* signal the release */
lradc->ts_valid = false;
input_report_key(lradc->ts_input, BTN_TOUCH, 0);
input_sync(lradc->ts_input);
}
/* if it is released, wait for the next touch via IRQ */
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1);
mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
}
/* touchscreen's state machine */
static void mxs_lradc_handle_touch(struct mxs_lradc *lradc)
{
int val;
switch (lradc->cur_plate) {
case LRADC_TOUCH:
/*
* start with the Y-pos, because it uses nearly the same plate
* settings like the touch detection
*/
if (mxs_lradc_check_touch_event(lradc)) {
mxs_lradc_reg_clear(lradc,
LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
LRADC_CTRL1);
mxs_lradc_prepare_y_pos(lradc);
}
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ,
LRADC_CTRL1);
return;
case LRADC_SAMPLE_Y:
val = mxs_lradc_read_ts_channel(lradc);
if (val < 0) {
mxs_lradc_enable_touch_detection(lradc); /* re-start */
return;
}
lradc->ts_y_pos = val;
mxs_lradc_prepare_x_pos(lradc);
return;
case LRADC_SAMPLE_X:
val = mxs_lradc_read_ts_channel(lradc);
if (val < 0) {
mxs_lradc_enable_touch_detection(lradc); /* re-start */
return;
}
lradc->ts_x_pos = val;
mxs_lradc_prepare_pressure(lradc);
return;
case LRADC_SAMPLE_PRESSURE:
lradc->ts_pressure =
mxs_lradc_read_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
mxs_lradc_complete_touch_event(lradc);
return;
case LRADC_SAMPLE_VALID:
val = mxs_lradc_read_ts_channel(lradc); /* ignore the value */
mxs_lradc_finish_touch_event(lradc, 1);
break;
}
}
/* /*
* Raw I/O operations * Raw I/O operations
*/ */
...@@ -262,21 +790,20 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev, ...@@ -262,21 +790,20 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
* Virtual channel 0 is always used here as the others are always not * Virtual channel 0 is always used here as the others are always not
* used if doing raw sampling. * used if doing raw sampling.
*/ */
writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, if (lradc->soc == IMX28_LRADC)
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); LRADC_CTRL1);
mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
/* Clean the slot's previous content, then set new one. */ /* Clean the slot's previous content, then set new one. */
writel(LRADC_CTRL4_LRADCSELECT_MASK(0), mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0), LRADC_CTRL4);
lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR); mxs_lradc_reg_set(lradc, chan->channel, LRADC_CTRL4);
writel(chan->channel, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
writel(0, lradc->base + LRADC_CH(0)); mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0));
/* Enable the IRQ and start sampling the channel. */ /* Enable the IRQ and start sampling the channel. */
writel(LRADC_CTRL1_LRADC_IRQ_EN(0), mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET); mxs_lradc_reg_set(lradc, 1 << 0, LRADC_CTRL0);
writel(1 << 0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
/* Wait for completion on the channel, 1 second max. */ /* Wait for completion on the channel, 1 second max. */
ret = wait_for_completion_killable_timeout(&lradc->completion, HZ); ret = wait_for_completion_killable_timeout(&lradc->completion, HZ);
...@@ -290,8 +817,7 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev, ...@@ -290,8 +817,7 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
ret = IIO_VAL_INT; ret = IIO_VAL_INT;
err: err:
writel(LRADC_CTRL1_LRADC_IRQ_EN(0), mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
mutex_unlock(&lradc->lock); mutex_unlock(&lradc->lock);
...@@ -303,220 +829,33 @@ static const struct iio_info mxs_lradc_iio_info = { ...@@ -303,220 +829,33 @@ static const struct iio_info mxs_lradc_iio_info = {
.read_raw = mxs_lradc_read_raw, .read_raw = mxs_lradc_read_raw,
}; };
/*
* Touchscreen handling
*/
enum lradc_ts_plate {
LRADC_SAMPLE_X,
LRADC_SAMPLE_Y,
LRADC_SAMPLE_PRESSURE,
};
static int mxs_lradc_ts_touched(struct mxs_lradc *lradc)
{
uint32_t reg;
/* Enable touch detection. */
writel(LRADC_CTRL0_PLATE_MASK,
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
msleep(LRADC_TS_SAMPLE_DELAY_MS);
reg = readl(lradc->base + LRADC_STATUS);
return reg & LRADC_STATUS_TOUCH_DETECT_RAW;
}
static int32_t mxs_lradc_ts_sample(struct mxs_lradc *lradc,
enum lradc_ts_plate plate, int change)
{
unsigned long delay, jiff;
uint32_t reg, ctrl0 = 0, chan = 0;
/* The touchscreen always uses CTRL4 slot #7. */
const uint8_t slot = 7;
uint32_t val;
/*
* There are three correct configurations of the controller sampling
* the touchscreen, each of these configuration provides different
* information from the touchscreen.
*
* The following table describes the sampling configurations:
* +-------------+-------+-------+-------+
* | Wire \ Axis | X | Y | Z |
* +---------------------+-------+-------+
* | X+ (CH2) | HI | TS | TS |
* +-------------+-------+-------+-------+
* | X- (CH4) | LO | SH | HI |
* +-------------+-------+-------+-------+
* | Y+ (CH3) | SH | HI | HI |
* +-------------+-------+-------+-------+
* | Y- (CH5) | TS | LO | SH |
* +-------------+-------+-------+-------+
*
* HI ... strong '1' ; LO ... strong '0'
* SH ... sample here ; TS ... tri-state
*
* There are a few other ways of obtaining the Z coordinate
* (aka. pressure), but the one in the table seems to be the
* most reliable one.
*/
switch (plate) {
case LRADC_SAMPLE_X:
ctrl0 = LRADC_CTRL0_XPPSW | LRADC_CTRL0_XNNSW;
chan = 3;
break;
case LRADC_SAMPLE_Y:
ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_YNNSW;
chan = 4;
break;
case LRADC_SAMPLE_PRESSURE:
ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_XNNSW;
chan = 5;
break;
}
if (change) {
writel(LRADC_CTRL0_PLATE_MASK,
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
writel(ctrl0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
writel(LRADC_CTRL4_LRADCSELECT_MASK(slot),
lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
writel(chan << LRADC_CTRL4_LRADCSELECT_OFFSET(slot),
lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
}
writel(0xffffffff, lradc->base + LRADC_CH(slot) + STMP_OFFSET_REG_CLR);
writel(1 << slot, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
delay = jiffies + msecs_to_jiffies(LRADC_TS_SAMPLE_DELAY_MS);
do {
jiff = jiffies;
reg = readl_relaxed(lradc->base + LRADC_CTRL1);
if (reg & LRADC_CTRL1_LRADC_IRQ(slot))
break;
} while (time_before(jiff, delay));
writel(LRADC_CTRL1_LRADC_IRQ(slot),
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
if (time_after_eq(jiff, delay))
return -ETIMEDOUT;
val = readl(lradc->base + LRADC_CH(slot));
val &= LRADC_CH_VALUE_MASK;
return val;
}
static int32_t mxs_lradc_ts_sample_filter(struct mxs_lradc *lradc,
enum lradc_ts_plate plate)
{
int32_t val, tot = 0;
int i;
val = mxs_lradc_ts_sample(lradc, plate, 1);
/* Delay a bit so the touchscreen is stable. */
mdelay(2);
for (i = 0; i < LRADC_TS_SAMPLE_AMOUNT; i++) {
val = mxs_lradc_ts_sample(lradc, plate, 0);
tot += val;
}
return tot / LRADC_TS_SAMPLE_AMOUNT;
}
static void mxs_lradc_ts_work(struct work_struct *ts_work)
{
struct mxs_lradc *lradc = container_of(ts_work,
struct mxs_lradc, ts_work);
int val_x, val_y, val_p;
bool valid = false;
while (mxs_lradc_ts_touched(lradc)) {
/* Disable touch detector so we can sample the touchscreen. */
writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
if (likely(valid)) {
input_report_abs(lradc->ts_input, ABS_X, val_x);
input_report_abs(lradc->ts_input, ABS_Y, val_y);
input_report_abs(lradc->ts_input, ABS_PRESSURE, val_p);
input_report_key(lradc->ts_input, BTN_TOUCH, 1);
input_sync(lradc->ts_input);
}
valid = false;
val_x = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_X);
if (val_x < 0)
continue;
val_y = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_Y);
if (val_y < 0)
continue;
val_p = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_PRESSURE);
if (val_p < 0)
continue;
valid = true;
}
input_report_abs(lradc->ts_input, ABS_PRESSURE, 0);
input_report_key(lradc->ts_input, BTN_TOUCH, 0);
input_sync(lradc->ts_input);
/* Do not restart the TS IRQ if the driver is shutting down. */
if (lradc->stop_touchscreen)
return;
/* Restart the touchscreen interrupts. */
writel(LRADC_CTRL1_TOUCH_DETECT_IRQ,
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
}
static int mxs_lradc_ts_open(struct input_dev *dev) static int mxs_lradc_ts_open(struct input_dev *dev)
{ {
struct mxs_lradc *lradc = input_get_drvdata(dev); struct mxs_lradc *lradc = input_get_drvdata(dev);
/* The touchscreen is starting. */
lradc->stop_touchscreen = false;
/* Enable the touch-detect circuitry. */ /* Enable the touch-detect circuitry. */
writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE, mxs_lradc_enable_touch_detection(lradc);
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
/* Enable the touch-detect IRQ. */
writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
return 0; return 0;
} }
static void mxs_lradc_ts_close(struct input_dev *dev) static void mxs_lradc_disable_ts(struct mxs_lradc *lradc)
{ {
struct mxs_lradc *lradc = input_get_drvdata(dev); /* stop all interrupts from firing */
mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
LRADC_CTRL1_LRADC_IRQ_EN(2) | LRADC_CTRL1_LRADC_IRQ_EN(3) |
LRADC_CTRL1_LRADC_IRQ_EN(4) | LRADC_CTRL1_LRADC_IRQ_EN(5),
LRADC_CTRL1);
/* Indicate the touchscreen is stopping. */ /* Power-down touchscreen touch-detect circuitry. */
lradc->stop_touchscreen = true; mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
mb(); }
/* Wait until touchscreen thread finishes any possible remnants. */
cancel_work_sync(&lradc->ts_work);
/* Disable touchscreen touch-detect IRQ. */ static void mxs_lradc_ts_close(struct input_dev *dev)
writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, {
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); struct mxs_lradc *lradc = input_get_drvdata(dev);
/* Power-down touchscreen touch-detect circuitry. */ mxs_lradc_disable_ts(lradc);
writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
} }
static int mxs_lradc_ts_register(struct mxs_lradc *lradc) static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
...@@ -562,8 +901,7 @@ static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc) ...@@ -562,8 +901,7 @@ static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc)
if (!lradc->use_touchscreen) if (!lradc->use_touchscreen)
return; return;
cancel_work_sync(&lradc->ts_work); mxs_lradc_disable_ts(lradc);
input_unregister_device(lradc->ts_input); input_unregister_device(lradc->ts_input);
} }
...@@ -576,31 +914,24 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data) ...@@ -576,31 +914,24 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
struct mxs_lradc *lradc = iio_priv(iio); struct mxs_lradc *lradc = iio_priv(iio);
unsigned long reg = readl(lradc->base + LRADC_CTRL1); unsigned long reg = readl(lradc->base + LRADC_CTRL1);
const uint32_t ts_irq_mask = const uint32_t ts_irq_mask =
LRADC_CTRL1_TOUCH_DETECT_IRQ_EN | LRADC_CTRL1_TOUCH_DETECT_IRQ |
LRADC_CTRL1_TOUCH_DETECT_IRQ; LRADC_CTRL1_LRADC_IRQ(2) |
LRADC_CTRL1_LRADC_IRQ(3) |
LRADC_CTRL1_LRADC_IRQ(4) |
LRADC_CTRL1_LRADC_IRQ(5);
if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK)) if (!(reg & mxs_lradc_irq_mask(lradc)))
return IRQ_NONE; return IRQ_NONE;
/* if (lradc->use_touchscreen && (reg & ts_irq_mask))
* Touchscreen IRQ handling code has priority and therefore mxs_lradc_handle_touch(lradc);
* is placed here. In case touchscreen IRQ arrives, disable
* it ASAP
*/
if (reg & LRADC_CTRL1_TOUCH_DETECT_IRQ) {
writel(ts_irq_mask,
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
if (!lradc->stop_touchscreen)
schedule_work(&lradc->ts_work);
}
if (iio_buffer_enabled(iio)) if (iio_buffer_enabled(iio))
iio_trigger_poll(iio->trig, iio_get_time_ns()); iio_trigger_poll(iio->trig, iio_get_time_ns());
else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
complete(&lradc->completion); complete(&lradc->completion);
writel(reg & LRADC_CTRL1_LRADC_IRQ_MASK, mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc), LRADC_CTRL1);
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -619,7 +950,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p) ...@@ -619,7 +950,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) { for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
lradc->buffer[j] = readl(lradc->base + LRADC_CH(j)); lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
writel(chan_value, lradc->base + LRADC_CH(j)); mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(j));
lradc->buffer[j] &= LRADC_CH_VALUE_MASK; lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP; lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
j++; j++;
...@@ -638,7 +969,7 @@ static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state) ...@@ -638,7 +969,7 @@ static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state)
struct mxs_lradc *lradc = iio_priv(iio); struct mxs_lradc *lradc = iio_priv(iio);
const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR; const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
writel(LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + st); mxs_lradc_reg_wrt(lradc, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
return 0; return 0;
} }
...@@ -714,29 +1045,27 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio) ...@@ -714,29 +1045,27 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
if (ret < 0) if (ret < 0)
goto err_buf; goto err_buf;
writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, if (lradc->soc == IMX28_LRADC)
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); LRADC_CTRL1);
mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) { for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs); ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs); ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs); ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
writel(chan_value, lradc->base + LRADC_CH(ofs)); mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(ofs));
bitmap_set(&enable, ofs, 1); bitmap_set(&enable, ofs, 1);
ofs++; ofs++;
} }
writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK, mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR); LRADC_DELAY_KICK, LRADC_DELAY(0));
mxs_lradc_reg_clear(lradc, ctrl4_clr, LRADC_CTRL4);
writel(ctrl4_clr, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR); mxs_lradc_reg_set(lradc, ctrl4_set, LRADC_CTRL4);
writel(ctrl4_set, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET); mxs_lradc_reg_set(lradc, ctrl1_irq, LRADC_CTRL1);
mxs_lradc_reg_set(lradc, enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET); LRADC_DELAY(0));
writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET);
return 0; return 0;
...@@ -751,12 +1080,13 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio) ...@@ -751,12 +1080,13 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
{ {
struct mxs_lradc *lradc = iio_priv(iio); struct mxs_lradc *lradc = iio_priv(iio);
writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK, mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR); LRADC_DELAY_KICK, LRADC_DELAY(0));
writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, if (lradc->soc == IMX28_LRADC)
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
LRADC_CTRL1);
kfree(lradc->buffer); kfree(lradc->buffer);
mutex_unlock(&lradc->lock); mutex_unlock(&lradc->lock);
...@@ -851,24 +1181,25 @@ static int mxs_lradc_hw_init(struct mxs_lradc *lradc) ...@@ -851,24 +1181,25 @@ static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
return ret; return ret;
/* Configure DELAY CHANNEL 0 for generic ADC sampling. */ /* Configure DELAY CHANNEL 0 for generic ADC sampling. */
writel(adc_cfg, lradc->base + LRADC_DELAY(0)); mxs_lradc_reg_wrt(lradc, adc_cfg, LRADC_DELAY(0));
/* Disable remaining DELAY CHANNELs */ /* Disable remaining DELAY CHANNELs */
writel(0, lradc->base + LRADC_DELAY(1)); mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(1));
writel(0, lradc->base + LRADC_DELAY(2)); mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
writel(0, lradc->base + LRADC_DELAY(3)); mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
/* Configure the touchscreen type */ /* Configure the touchscreen type */
writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE, if (lradc->soc == IMX28_LRADC) {
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); mxs_lradc_reg_clear(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
LRADC_CTRL0);
if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE) { if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE, mxs_lradc_reg_set(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET); LRADC_CTRL0);
} }
/* Start internal temperature sensing. */ /* Start internal temperature sensing. */
writel(0, lradc->base + LRADC_CTRL2); mxs_lradc_reg_wrt(lradc, 0, LRADC_CTRL2);
return 0; return 0;
} }
...@@ -877,11 +1208,10 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc) ...@@ -877,11 +1208,10 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
{ {
int i; int i;
writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK, mxs_lradc_reg_clear(lradc, mxs_lradc_irq_en_mask(lradc), LRADC_CTRL1);
lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++) for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
writel(0, lradc->base + LRADC_DELAY(i)); mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(i));
} }
static const struct of_device_id mxs_lradc_dt_ids[] = { static const struct of_device_id mxs_lradc_dt_ids[] = {
...@@ -891,6 +1221,52 @@ static const struct of_device_id mxs_lradc_dt_ids[] = { ...@@ -891,6 +1221,52 @@ static const struct of_device_id mxs_lradc_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids); MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
struct device_node *lradc_node)
{
int ret;
u32 ts_wires = 0, adapt;
ret = of_property_read_u32(lradc_node, "fsl,lradc-touchscreen-wires",
&ts_wires);
if (ret)
return -ENODEV; /* touchscreen feature disabled */
switch (ts_wires) {
case 4:
lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
break;
case 5:
if (lradc->soc == IMX28_LRADC) {
lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
break;
}
/* fall through an error message for i.MX23 */
default:
dev_err(lradc->dev,
"Unsupported number of touchscreen wires (%d)\n",
ts_wires);
return -EINVAL;
}
lradc->over_sample_cnt = 4;
ret = of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt);
if (ret == 0)
lradc->over_sample_cnt = adapt;
lradc->over_sample_delay = 2;
ret = of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt);
if (ret == 0)
lradc->over_sample_delay = adapt;
lradc->settling_delay = 10;
ret = of_property_read_u32(lradc_node, "fsl,settling", &adapt);
if (ret == 0)
lradc->settling_delay = adapt;
return 0;
}
static int mxs_lradc_probe(struct platform_device *pdev) static int mxs_lradc_probe(struct platform_device *pdev)
{ {
const struct of_device_id *of_id = const struct of_device_id *of_id =
...@@ -902,8 +1278,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) ...@@ -902,8 +1278,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
struct mxs_lradc *lradc; struct mxs_lradc *lradc;
struct iio_dev *iio; struct iio_dev *iio;
struct resource *iores; struct resource *iores;
uint32_t ts_wires = 0; int ret = 0, touch_ret;
int ret = 0;
int i; int i;
/* Allocate the IIO device. */ /* Allocate the IIO device. */
...@@ -914,6 +1289,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) ...@@ -914,6 +1289,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
} }
lradc = iio_priv(iio); lradc = iio_priv(iio);
lradc->soc = (enum mxs_lradc_id)of_id->data;
/* Grab the memory area */ /* Grab the memory area */
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -922,20 +1298,18 @@ static int mxs_lradc_probe(struct platform_device *pdev) ...@@ -922,20 +1298,18 @@ static int mxs_lradc_probe(struct platform_device *pdev)
if (IS_ERR(lradc->base)) if (IS_ERR(lradc->base))
return PTR_ERR(lradc->base); return PTR_ERR(lradc->base);
INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work); lradc->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(lradc->clk)) {
dev_err(dev, "Failed to get the delay unit clock\n");
return PTR_ERR(lradc->clk);
}
ret = clk_prepare_enable(lradc->clk);
if (ret != 0) {
dev_err(dev, "Failed to enable the delay unit clock\n");
return ret;
}
/* Check if touchscreen is enabled in DT. */ touch_ret = mxs_lradc_probe_touchscreen(lradc, node);
ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
&ts_wires);
if (ret)
dev_info(dev, "Touchscreen not enabled.\n");
else if (ts_wires == 4)
lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
else if (ts_wires == 5)
lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
else
dev_warn(dev, "Unsupported number of touchscreen wires (%d)\n",
ts_wires);
/* Grab all IRQ sources */ /* Grab all IRQ sources */
for (i = 0; i < of_cfg->irq_count; i++) { for (i = 0; i < of_cfg->irq_count; i++) {
...@@ -979,9 +1353,11 @@ static int mxs_lradc_probe(struct platform_device *pdev) ...@@ -979,9 +1353,11 @@ static int mxs_lradc_probe(struct platform_device *pdev)
goto err_dev; goto err_dev;
/* Register the touchscreen input device. */ /* Register the touchscreen input device. */
ret = mxs_lradc_ts_register(lradc); if (touch_ret == 0) {
if (ret) ret = mxs_lradc_ts_register(lradc);
goto err_ts_register; if (ret)
goto err_ts_register;
}
/* Register IIO device. */ /* Register IIO device. */
ret = iio_device_register(iio); ret = iio_device_register(iio);
...@@ -1014,6 +1390,7 @@ static int mxs_lradc_remove(struct platform_device *pdev) ...@@ -1014,6 +1390,7 @@ static int mxs_lradc_remove(struct platform_device *pdev)
mxs_lradc_trigger_remove(iio); mxs_lradc_trigger_remove(iio);
iio_triggered_buffer_cleanup(iio); iio_triggered_buffer_cleanup(iio);
clk_disable_unprepare(lradc->clk);
return 0; return 0;
} }
......
...@@ -168,10 +168,9 @@ static int spear_read_raw(struct iio_dev *indio_dev, ...@@ -168,10 +168,9 @@ static int spear_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_mv = (info->vref_external * 1000) >> DATA_BITS; *val = info->vref_external;
*val = scale_mv / 1000; *val2 = DATA_BITS;
*val2 = (scale_mv % 1000) * 1000; return IIO_VAL_FRACTIONAL_LOG2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
......
...@@ -656,20 +656,21 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, ...@@ -656,20 +656,21 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
switch (chan->type) { switch (chan->type) {
case IIO_CAPACITANCE: case IIO_CAPACITANCE:
/* 8.192pf / 2^24 */ /* 8.192pf / 2^24 */
*val2 = 488;
*val = 0; *val = 0;
*val2 = 488;
ret = IIO_VAL_INT_PLUS_NANO;
break; break;
case IIO_VOLTAGE: case IIO_VOLTAGE:
/* 1170mV / 2^23 */ /* 1170mV / 2^23 */
*val2 = 139475; *val = 1170;
*val = 0; *val2 = 23;
ret = IIO_VAL_FRACTIONAL_LOG2;
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
goto out; break;
} }
ret = IIO_VAL_INT_PLUS_NANO;
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
......
...@@ -67,7 +67,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, ...@@ -67,7 +67,6 @@ static ssize_t ad9852_set_parameter(struct device *dev,
const char *buf, const char *buf,
size_t len) size_t len)
{ {
struct spi_message msg;
struct spi_transfer xfer; struct spi_transfer xfer;
int ret; int ret;
struct ad9852_config *config = (struct ad9852_config *)buf; struct ad9852_config *config = (struct ad9852_config *)buf;
...@@ -78,99 +77,77 @@ static ssize_t ad9852_set_parameter(struct device *dev, ...@@ -78,99 +77,77 @@ static ssize_t ad9852_set_parameter(struct device *dev,
xfer.tx_buf = &config->phajst0[0]; xfer.tx_buf = &config->phajst0[0];
mutex_lock(&st->lock); mutex_lock(&st->lock);
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 3; xfer.len = 3;
xfer.tx_buf = &config->phajst1[0]; xfer.tx_buf = &config->phajst1[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 6; xfer.len = 6;
xfer.tx_buf = &config->fretun1[0]; xfer.tx_buf = &config->fretun1[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 6; xfer.len = 6;
xfer.tx_buf = &config->fretun2[0]; xfer.tx_buf = &config->fretun2[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 6; xfer.len = 6;
xfer.tx_buf = &config->dltafre[0]; xfer.tx_buf = &config->dltafre[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->updtclk[0]; xfer.tx_buf = &config->updtclk[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 4; xfer.len = 4;
xfer.tx_buf = &config->ramprat[0]; xfer.tx_buf = &config->ramprat[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->control[0]; xfer.tx_buf = &config->control[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 3; xfer.len = 3;
xfer.tx_buf = &config->outpskm[0]; xfer.tx_buf = &config->outpskm[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 2; xfer.len = 2;
xfer.tx_buf = &config->outpskr[0]; xfer.tx_buf = &config->outpskr[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 3; xfer.len = 3;
xfer.tx_buf = &config->daccntl[0]; xfer.tx_buf = &config->daccntl[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
error_ret: error_ret:
......
...@@ -119,7 +119,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, ...@@ -119,7 +119,6 @@ static ssize_t ad9910_set_parameter(struct device *dev,
const char *buf, const char *buf,
size_t len) size_t len)
{ {
struct spi_message msg;
struct spi_transfer xfer; struct spi_transfer xfer;
int ret; int ret;
struct ad9910_config *config = (struct ad9910_config *)buf; struct ad9910_config *config = (struct ad9910_config *)buf;
...@@ -130,152 +129,118 @@ static ssize_t ad9910_set_parameter(struct device *dev, ...@@ -130,152 +129,118 @@ static ssize_t ad9910_set_parameter(struct device *dev,
xfer.tx_buf = &config->auxdac[0]; xfer.tx_buf = &config->auxdac[0];
mutex_lock(&st->lock); mutex_lock(&st->lock);
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->ioupd[0]; xfer.tx_buf = &config->ioupd[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->ftw[0]; xfer.tx_buf = &config->ftw[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 3; xfer.len = 3;
xfer.tx_buf = &config->pow[0]; xfer.tx_buf = &config->pow[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->asf[0]; xfer.tx_buf = &config->asf[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->multc[0]; xfer.tx_buf = &config->multc[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->dig_rampl[0]; xfer.tx_buf = &config->dig_rampl[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->dig_ramps[0]; xfer.tx_buf = &config->dig_ramps[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->dig_rampr[0]; xfer.tx_buf = &config->dig_rampr[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep0[0]; xfer.tx_buf = &config->sin_tonep0[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep1[0]; xfer.tx_buf = &config->sin_tonep1[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep2[0]; xfer.tx_buf = &config->sin_tonep2[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep3[0]; xfer.tx_buf = &config->sin_tonep3[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep4[0]; xfer.tx_buf = &config->sin_tonep4[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep5[0]; xfer.tx_buf = &config->sin_tonep5[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep6[0]; xfer.tx_buf = &config->sin_tonep6[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 9; xfer.len = 9;
xfer.tx_buf = &config->sin_tonep7[0]; xfer.tx_buf = &config->sin_tonep7[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
error_ret: error_ret:
...@@ -288,7 +253,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0); ...@@ -288,7 +253,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
static void ad9910_init(struct ad9910_state *st) static void ad9910_init(struct ad9910_state *st)
{ {
struct spi_message msg;
struct spi_transfer xfer; struct spi_transfer xfer;
int ret; int ret;
u8 cfr[5]; u8 cfr[5];
...@@ -304,9 +268,7 @@ static void ad9910_init(struct ad9910_state *st) ...@@ -304,9 +268,7 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &cfr; xfer.tx_buf = &cfr;
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
...@@ -319,9 +281,7 @@ static void ad9910_init(struct ad9910_state *st) ...@@ -319,9 +281,7 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &cfr; xfer.tx_buf = &cfr;
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
...@@ -334,9 +294,7 @@ static void ad9910_init(struct ad9910_state *st) ...@@ -334,9 +294,7 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &cfr; xfer.tx_buf = &cfr;
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
......
...@@ -60,7 +60,6 @@ static ssize_t ad9951_set_parameter(struct device *dev, ...@@ -60,7 +60,6 @@ static ssize_t ad9951_set_parameter(struct device *dev,
const char *buf, const char *buf,
size_t len) size_t len)
{ {
struct spi_message msg;
struct spi_transfer xfer; struct spi_transfer xfer;
int ret; int ret;
struct ad9951_config *config = (struct ad9951_config *)buf; struct ad9951_config *config = (struct ad9951_config *)buf;
...@@ -71,36 +70,28 @@ static ssize_t ad9951_set_parameter(struct device *dev, ...@@ -71,36 +70,28 @@ static ssize_t ad9951_set_parameter(struct device *dev,
xfer.tx_buf = &config->asf[0]; xfer.tx_buf = &config->asf[0];
mutex_lock(&st->lock); mutex_lock(&st->lock);
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 2; xfer.len = 2;
xfer.tx_buf = &config->arr[0]; xfer.tx_buf = &config->arr[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &config->ftw0[0]; xfer.tx_buf = &config->ftw0[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
xfer.len = 3; xfer.len = 3;
xfer.tx_buf = &config->ftw1[0]; xfer.tx_buf = &config->ftw1[0];
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
error_ret: error_ret:
...@@ -113,7 +104,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0); ...@@ -113,7 +104,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
static void ad9951_init(struct ad9951_state *st) static void ad9951_init(struct ad9951_state *st)
{ {
struct spi_message msg;
struct spi_transfer xfer; struct spi_transfer xfer;
int ret; int ret;
u8 cfr[5]; u8 cfr[5];
...@@ -129,9 +119,7 @@ static void ad9951_init(struct ad9951_state *st) ...@@ -129,9 +119,7 @@ static void ad9951_init(struct ad9951_state *st)
xfer.len = 5; xfer.len = 5;
xfer.tx_buf = &cfr; xfer.tx_buf = &cfr;
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
...@@ -143,9 +131,7 @@ static void ad9951_init(struct ad9951_state *st) ...@@ -143,9 +131,7 @@ static void ad9951_init(struct ad9951_state *st)
xfer.len = 4; xfer.len = 4;
xfer.tx_buf = &cfr; xfer.tx_buf = &cfr;
spi_message_init(&msg); ret = spi_sync_transfer(st->sdev, &xfer, 1);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(st->sdev, &msg);
if (ret) if (ret)
goto error_ret; goto error_ret;
......
...@@ -29,16 +29,11 @@ ...@@ -29,16 +29,11 @@
#define HMC5843_CONFIG_REG_B 0x01 #define HMC5843_CONFIG_REG_B 0x01
#define HMC5843_MODE_REG 0x02 #define HMC5843_MODE_REG 0x02
#define HMC5843_DATA_OUT_X_MSB_REG 0x03 #define HMC5843_DATA_OUT_X_MSB_REG 0x03
#define HMC5843_DATA_OUT_X_LSB_REG 0x04
#define HMC5843_DATA_OUT_Y_MSB_REG 0x05 #define HMC5843_DATA_OUT_Y_MSB_REG 0x05
#define HMC5843_DATA_OUT_Y_LSB_REG 0x06
#define HMC5843_DATA_OUT_Z_MSB_REG 0x07 #define HMC5843_DATA_OUT_Z_MSB_REG 0x07
#define HMC5843_DATA_OUT_Z_LSB_REG 0x08
/* Beware: Y and Z are exchanged on HMC5883 */ /* Beware: Y and Z are exchanged on HMC5883 */
#define HMC5883_DATA_OUT_Z_MSB_REG 0x05 #define HMC5883_DATA_OUT_Z_MSB_REG 0x05
#define HMC5883_DATA_OUT_Z_LSB_REG 0x06
#define HMC5883_DATA_OUT_Y_MSB_REG 0x07 #define HMC5883_DATA_OUT_Y_MSB_REG 0x07
#define HMC5883_DATA_OUT_Y_LSB_REG 0x08
#define HMC5843_STATUS_REG 0x09 #define HMC5843_STATUS_REG 0x09
enum hmc5843_ids { enum hmc5843_ids {
...@@ -56,17 +51,11 @@ enum hmc5843_ids { ...@@ -56,17 +51,11 @@ enum hmc5843_ids {
#define HMC5843_RANGE_GAIN_DEFAULT 0x01 #define HMC5843_RANGE_GAIN_DEFAULT 0x01
#define HMC5843_RANGE_GAIN_MAX 0x07 #define HMC5843_RANGE_GAIN_MAX 0x07
/* /* Device status */
* Device status
*/
#define HMC5843_DATA_READY 0x01 #define HMC5843_DATA_READY 0x01
#define HMC5843_DATA_OUTPUT_LOCK 0x02 #define HMC5843_DATA_OUTPUT_LOCK 0x02
/* Does not exist on HMC5883, not used */
#define HMC5843_VOLTAGE_REGULATOR_ENABLED 0x04
/* /* Mode register configuration */
* Mode register configuration
*/
#define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00 #define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00
#define HMC5843_MODE_CONVERSION_SINGLE 0x01 #define HMC5843_MODE_CONVERSION_SINGLE 0x01
#define HMC5843_MODE_IDLE 0x02 #define HMC5843_MODE_IDLE 0x02
...@@ -78,21 +67,18 @@ enum hmc5843_ids { ...@@ -78,21 +67,18 @@ enum hmc5843_ids {
* HMC5883: Typical data output rate * HMC5883: Typical data output rate
*/ */
#define HMC5843_RATE_OFFSET 0x02 #define HMC5843_RATE_OFFSET 0x02
#define HMC5843_RATE_DEFAULT 0x04
#define HMC5843_RATE_BITMASK 0x1C #define HMC5843_RATE_BITMASK 0x1C
#define HMC5843_RATE_NOT_USED 0x07 #define HMC5843_RATE_NOT_USED 0x07
/* /* Device measurement configuration */
* Device measurement configuration
*/
#define HMC5843_MEAS_CONF_NORMAL 0x00 #define HMC5843_MEAS_CONF_NORMAL 0x00
#define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01 #define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01
#define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02 #define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02
#define HMC5843_MEAS_CONF_NOT_USED 0x03 #define HMC5843_MEAS_CONF_NOT_USED 0x03
#define HMC5843_MEAS_CONF_MASK 0x03 #define HMC5843_MEAS_CONF_MASK 0x03
/* /* Scaling factors: 10000000/Gain */
* Scaling factors: 10000000/Gain
*/
static const int hmc5843_regval_to_nanoscale[] = { static const int hmc5843_regval_to_nanoscale[] = {
6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
}; };
...@@ -164,24 +150,26 @@ static const int hmc5883l_regval_to_input_field_mga[] = { ...@@ -164,24 +150,26 @@ static const int hmc5883l_regval_to_input_field_mga[] = {
* 6 | 50 | 75 * 6 | 50 | 75
* 7 | Not used | Not used * 7 | Not used | Not used
*/ */
static const char * const hmc5843_regval_to_sample_freq[] = { static const int hmc5843_regval_to_samp_freq[7][2] = {
"0.5", "1", "2", "5", "10", "20", "50", {0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
}; };
static const char * const hmc5883_regval_to_sample_freq[] = { static const int hmc5883_regval_to_samp_freq[7][2] = {
"0.75", "1.5", "3", "7.5", "15", "30", "75", {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
{75, 0}
}; };
/* Describe chip variants */ /* Describe chip variants */
struct hmc5843_chip_info { struct hmc5843_chip_info {
const struct iio_chan_spec *channels; const struct iio_chan_spec *channels;
const char * const *regval_to_sample_freq; const int (*regval_to_samp_freq)[2];
const int *regval_to_input_field_mga; const int *regval_to_input_field_mga;
const int *regval_to_nanoscale; const int *regval_to_nanoscale;
}; };
/* Each client has this additional data */ /* Each client has this additional data */
struct hmc5843_data { struct hmc5843_data {
struct i2c_client *client;
struct mutex lock; struct mutex lock;
u8 rate; u8 rate;
u8 meas_conf; u8 meas_conf;
...@@ -200,18 +188,15 @@ static s32 hmc5843_configure(struct i2c_client *client, ...@@ -200,18 +188,15 @@ static s32 hmc5843_configure(struct i2c_client *client,
} }
/* Return the measurement value from the specified channel */ /* Return the measurement value from the specified channel */
static int hmc5843_read_measurement(struct iio_dev *indio_dev, static int hmc5843_read_measurement(struct hmc5843_data *data,
int address, int address, int *val)
int *val)
{ {
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
struct hmc5843_data *data = iio_priv(indio_dev);
s32 result; s32 result;
int tries = 150; int tries = 150;
mutex_lock(&data->lock); mutex_lock(&data->lock);
while (tries-- > 0) { while (tries-- > 0) {
result = i2c_smbus_read_byte_data(client, result = i2c_smbus_read_byte_data(data->client,
HMC5843_STATUS_REG); HMC5843_STATUS_REG);
if (result & HMC5843_DATA_READY) if (result & HMC5843_DATA_READY)
break; break;
...@@ -219,12 +204,12 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev, ...@@ -219,12 +204,12 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev,
} }
if (tries < 0) { if (tries < 0) {
dev_err(&client->dev, "data not ready\n"); dev_err(&data->client->dev, "data not ready\n");
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return -EIO; return -EIO;
} }
result = i2c_smbus_read_word_swapped(client, address); result = i2c_smbus_read_word_swapped(data->client, address);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
if (result < 0) if (result < 0)
return -EINVAL; return -EINVAL;
...@@ -318,15 +303,13 @@ static IIO_DEVICE_ATTR(operating_mode, ...@@ -318,15 +303,13 @@ static IIO_DEVICE_ATTR(operating_mode,
* and BN. * and BN.
* *
*/ */
static s32 hmc5843_set_meas_conf(struct i2c_client *client, static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
u8 meas_conf)
{ {
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct hmc5843_data *data = iio_priv(indio_dev);
u8 reg_val; u8 reg_val;
reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) | reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) |
(data->rate << HMC5843_RATE_OFFSET); (data->rate << HMC5843_RATE_OFFSET);
return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val); return i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
reg_val);
} }
static ssize_t hmc5843_show_measurement_configuration(struct device *dev, static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
...@@ -344,7 +327,6 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev, ...@@ -344,7 +327,6 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
size_t count) size_t count)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
struct hmc5843_data *data = iio_priv(indio_dev); struct hmc5843_data *data = iio_priv(indio_dev);
unsigned long meas_conf = 0; unsigned long meas_conf = 0;
int error; int error;
...@@ -357,7 +339,7 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev, ...@@ -357,7 +339,7 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
mutex_lock(&data->lock); mutex_lock(&data->lock);
dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf); dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf);
if (hmc5843_set_meas_conf(client, meas_conf)) { if (hmc5843_set_meas_conf(data, meas_conf)) {
count = -EINVAL; count = -EINVAL;
goto exit; goto exit;
} }
...@@ -374,111 +356,62 @@ static IIO_DEVICE_ATTR(meas_conf, ...@@ -374,111 +356,62 @@ static IIO_DEVICE_ATTR(meas_conf,
hmc5843_set_measurement_configuration, hmc5843_set_measurement_configuration,
0); 0);
static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev, static ssize_t hmc5843_show_int_plus_micros(char *buf,
struct device_attribute *attr, const int (*vals)[2], int n)
char *buf)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); size_t len = 0;
struct hmc5843_data *data = iio_priv(indio_dev);
ssize_t total_n = 0;
int i; int i;
for (i = 0; i < HMC5843_RATE_NOT_USED; i++) { for (i = 0; i < n; i++)
ssize_t n = sprintf(buf, "%s ", data->variant->regval_to_sample_freq[i]); len += scnprintf(buf + len, PAGE_SIZE - len,
buf += n; "%d.%d ", vals[i][0], vals[i][1]);
total_n += n;
}
/* replace trailing space by newline */
buf[-1] = '\n';
return total_n; /* replace trailing space by newline */
} buf[len - 1] = '\n';
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available);
static s32 hmc5843_set_rate(struct i2c_client *client,
u8 rate)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct hmc5843_data *data = iio_priv(indio_dev);
u8 reg_val;
if (rate >= HMC5843_RATE_NOT_USED) {
dev_err(&client->dev,
"data output rate is not supported\n");
return -EINVAL;
}
reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET); return len;
return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
} }
static int hmc5843_check_sampling_frequency(struct hmc5843_data *data, static int hmc5843_check_int_plus_micros(const int (*vals)[2], int n,
const char *buf) int val, int val2)
{ {
const char * const *samp_freq = data->variant->regval_to_sample_freq;
int i; int i;
for (i = 0; i < HMC5843_RATE_NOT_USED; i++) { for (i = 0; i < n; i++) {
if (sysfs_streq(buf, samp_freq[i])) if (val == vals[i][0] && val2 == vals[i][1])
return i; return i;
} }
return -EINVAL; return -EINVAL;
} }
static ssize_t hmc5843_set_sampling_frequency(struct device *dev, static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr, char *buf)
const char *buf, size_t count)
{ {
struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
struct iio_dev *indio_dev = dev_to_iio_dev(dev); return hmc5843_show_int_plus_micros(buf,
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); data->variant->regval_to_samp_freq, HMC5843_RATE_NOT_USED);
struct hmc5843_data *data = iio_priv(indio_dev); }
int rate;
rate = hmc5843_check_sampling_frequency(data, buf); static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
if (rate < 0) {
dev_err(&client->dev,
"sampling frequency is not supported\n");
return rate;
}
mutex_lock(&data->lock); static s32 hmc5843_set_rate(struct hmc5843_data *data, u8 rate)
dev_dbg(dev, "set rate to %d\n", rate); {
if (hmc5843_set_rate(client, rate)) { u8 reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET);
count = -EINVAL;
goto exit;
}
data->rate = rate;
exit: return i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
mutex_unlock(&data->lock); reg_val);
return count;
} }
static ssize_t hmc5843_show_sampling_frequency(struct device *dev, static int hmc5843_check_samp_freq(struct hmc5843_data *data,
struct device_attribute *attr, char *buf) int val, int val2)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); return hmc5843_check_int_plus_micros(
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); data->variant->regval_to_samp_freq, HMC5843_RATE_NOT_USED,
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); val, val2);
struct hmc5843_data *data = iio_priv(indio_dev);
s32 rate;
rate = i2c_smbus_read_byte_data(client, this_attr->address);
if (rate < 0)
return rate;
rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]);
} }
static IIO_DEVICE_ATTR(sampling_frequency,
S_IWUSR | S_IRUGO,
hmc5843_show_sampling_frequency,
hmc5843_set_sampling_frequency,
HMC5843_CONFIG_REG_A);
static ssize_t hmc5843_show_range_gain(struct device *dev, static ssize_t hmc5843_show_range_gain(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
...@@ -497,7 +430,6 @@ static ssize_t hmc5843_set_range_gain(struct device *dev, ...@@ -497,7 +430,6 @@ static ssize_t hmc5843_set_range_gain(struct device *dev,
size_t count) size_t count)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct hmc5843_data *data = iio_priv(indio_dev); struct hmc5843_data *data = iio_priv(indio_dev);
unsigned long range = 0; unsigned long range = 0;
...@@ -518,7 +450,7 @@ static ssize_t hmc5843_set_range_gain(struct device *dev, ...@@ -518,7 +450,7 @@ static ssize_t hmc5843_set_range_gain(struct device *dev,
data->range = range; data->range = range;
range = range << HMC5843_RANGE_GAIN_OFFSET; range = range << HMC5843_RANGE_GAIN_OFFSET;
if (i2c_smbus_write_byte_data(client, this_attr->address, range)) if (i2c_smbus_write_byte_data(data->client, this_attr->address, range))
count = -EINVAL; count = -EINVAL;
exit: exit:
...@@ -534,31 +466,58 @@ static IIO_DEVICE_ATTR(in_magn_range, ...@@ -534,31 +466,58 @@ static IIO_DEVICE_ATTR(in_magn_range,
static int hmc5843_read_raw(struct iio_dev *indio_dev, static int hmc5843_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, struct iio_chan_spec const *chan,
int *val, int *val2, int *val, int *val2, long mask)
long mask)
{ {
struct hmc5843_data *data = iio_priv(indio_dev); struct hmc5843_data *data = iio_priv(indio_dev);
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
return hmc5843_read_measurement(indio_dev, return hmc5843_read_measurement(data, chan->address, val);
chan->address,
val);
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = 0; *val = 0;
*val2 = data->variant->regval_to_nanoscale[data->range]; *val2 = data->variant->regval_to_nanoscale[data->range];
return IIO_VAL_INT_PLUS_NANO; return IIO_VAL_INT_PLUS_NANO;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = data->variant->regval_to_samp_freq[data->rate][0];
*val2 = data->variant->regval_to_samp_freq[data->rate][1];
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
static int hmc5843_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct hmc5843_data *data = iio_priv(indio_dev);
int ret, rate;
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
rate = hmc5843_check_samp_freq(data, val, val2);
if (rate < 0)
return -EINVAL;
mutex_lock(&data->lock);
ret = hmc5843_set_rate(data, rate);
if (ret >= 0)
data->rate = rate;
mutex_unlock(&data->lock);
return ret;
default:
return -EINVAL;
}
}
#define HMC5843_CHANNEL(axis, addr) \ #define HMC5843_CHANNEL(axis, addr) \
{ \ { \
.type = IIO_MAGN, \ .type = IIO_MAGN, \
.modified = 1, \ .modified = 1, \
.channel2 = IIO_MOD_##axis, \ .channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = addr \ .address = addr \
} }
...@@ -577,7 +536,6 @@ static const struct iio_chan_spec hmc5883_channels[] = { ...@@ -577,7 +536,6 @@ static const struct iio_chan_spec hmc5883_channels[] = {
static struct attribute *hmc5843_attributes[] = { static struct attribute *hmc5843_attributes[] = {
&iio_dev_attr_meas_conf.dev_attr.attr, &iio_dev_attr_meas_conf.dev_attr.attr,
&iio_dev_attr_operating_mode.dev_attr.attr, &iio_dev_attr_operating_mode.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_in_magn_range.dev_attr.attr, &iio_dev_attr_in_magn_range.dev_attr.attr,
&iio_dev_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL NULL
...@@ -590,49 +548,40 @@ static const struct attribute_group hmc5843_group = { ...@@ -590,49 +548,40 @@ static const struct attribute_group hmc5843_group = {
static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = { static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = { [HMC5843_ID] = {
.channels = hmc5843_channels, .channels = hmc5843_channels,
.regval_to_sample_freq = hmc5843_regval_to_sample_freq, .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
.regval_to_input_field_mga = .regval_to_input_field_mga =
hmc5843_regval_to_input_field_mga, hmc5843_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5843_regval_to_nanoscale, .regval_to_nanoscale = hmc5843_regval_to_nanoscale,
}, },
[HMC5883_ID] = { [HMC5883_ID] = {
.channels = hmc5883_channels, .channels = hmc5883_channels,
.regval_to_sample_freq = hmc5883_regval_to_sample_freq, .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
.regval_to_input_field_mga = .regval_to_input_field_mga =
hmc5883_regval_to_input_field_mga, hmc5883_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5883_regval_to_nanoscale, .regval_to_nanoscale = hmc5883_regval_to_nanoscale,
}, },
[HMC5883L_ID] = { [HMC5883L_ID] = {
.channels = hmc5883_channels, .channels = hmc5883_channels,
.regval_to_sample_freq = hmc5883_regval_to_sample_freq, .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
.regval_to_input_field_mga = .regval_to_input_field_mga =
hmc5883l_regval_to_input_field_mga, hmc5883l_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5883l_regval_to_nanoscale, .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
}, },
}; };
/* Called when we have found a new HMC58X3 */ static void hmc5843_init(struct hmc5843_data *data)
static void hmc5843_init_client(struct i2c_client *client,
const struct i2c_device_id *id)
{ {
struct iio_dev *indio_dev = i2c_get_clientdata(client); hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
struct hmc5843_data *data = iio_priv(indio_dev); hmc5843_set_rate(data, HMC5843_RATE_DEFAULT);
hmc5843_configure(data->client, HMC5843_MODE_CONVERSION_CONTINUOUS);
data->variant = &hmc5843_chip_info_tbl[id->driver_data]; i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
indio_dev->channels = data->variant->channels; HMC5843_RANGE_GAIN_DEFAULT);
indio_dev->num_channels = 3;
hmc5843_set_meas_conf(client, data->meas_conf);
hmc5843_set_rate(client, data->rate);
hmc5843_configure(client, data->operating_mode);
i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
mutex_init(&data->lock);
pr_info("%s initialized\n", id->name);
} }
static const struct iio_info hmc5843_info = { static const struct iio_info hmc5843_info = {
.attrs = &hmc5843_group, .attrs = &hmc5843_group,
.read_raw = &hmc5843_read_raw, .read_raw = &hmc5843_read_raw,
.write_raw = &hmc5843_write_raw,
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
}; };
...@@ -649,17 +598,19 @@ static int hmc5843_probe(struct i2c_client *client, ...@@ -649,17 +598,19 @@ static int hmc5843_probe(struct i2c_client *client,
/* default settings at probe */ /* default settings at probe */
data = iio_priv(indio_dev); data = iio_priv(indio_dev);
data->meas_conf = HMC5843_MEAS_CONF_NORMAL; data->client = client;
data->range = HMC5843_RANGE_GAIN_DEFAULT; data->variant = &hmc5843_chip_info_tbl[id->driver_data];
data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS; mutex_init(&data->lock);
i2c_set_clientdata(client, indio_dev); i2c_set_clientdata(client, indio_dev);
hmc5843_init_client(client, id);
indio_dev->info = &hmc5843_info; indio_dev->info = &hmc5843_info;
indio_dev->name = id->name; indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev; indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = data->variant->channels;
indio_dev->num_channels = 3;
hmc5843_init(data);
err = iio_device_register(indio_dev); err = iio_device_register(indio_dev);
if (err) if (err)
...@@ -687,10 +638,10 @@ static int hmc5843_suspend(struct device *dev) ...@@ -687,10 +638,10 @@ static int hmc5843_suspend(struct device *dev)
static int hmc5843_resume(struct device *dev) static int hmc5843_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
struct hmc5843_data *data = iio_priv(i2c_get_clientdata(client)); to_i2c_client(dev)));
hmc5843_configure(client, data->operating_mode); hmc5843_configure(data->client, data->operating_mode);
return 0; return 0;
} }
......
...@@ -47,11 +47,13 @@ struct hid_sensor_hub_attribute_info { ...@@ -47,11 +47,13 @@ struct hid_sensor_hub_attribute_info {
* @hdev: Stores the hid instance. * @hdev: Stores the hid instance.
* @vendor_id: Vendor id of hub device. * @vendor_id: Vendor id of hub device.
* @product_id: Product id of hub device. * @product_id: Product id of hub device.
* @ref_cnt: Number of MFD clients have opened this device
*/ */
struct hid_sensor_hub_device { struct hid_sensor_hub_device {
struct hid_device *hdev; struct hid_device *hdev;
u32 vendor_id; u32 vendor_id;
u32 product_id; u32 product_id;
int ref_cnt;
}; };
/** /**
...@@ -74,6 +76,22 @@ struct hid_sensor_hub_callbacks { ...@@ -74,6 +76,22 @@ struct hid_sensor_hub_callbacks {
void *priv); void *priv);
}; };
/**
* sensor_hub_device_open() - Open hub device
* @hsdev: Hub device instance.
*
* Used to open hid device for sensor hub.
*/
int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev);
/**
* sensor_hub_device_clode() - Close hub device
* @hsdev: Hub device instance.
*
* Used to clode hid device for sensor hub.
*/
void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev);
/* Registration functions */ /* Registration functions */
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment