diff options
author | Denis CIOCCA <denis.ciocca@st.com> | 2013-06-03 10:58:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2013-06-05 13:41:23 -0400 |
commit | 607a568ab69c5ac345a286267a27294888f8bb5f (patch) | |
tree | f52d27c3f06725c7078d6fe876a3a194e45322b4 /drivers/iio | |
parent | 762011d6193f8b9af9b491ded87dde3221d0600a (diff) |
iio:common: Removed stuff macros, added num_data_channels on st_sensors struct and added support on one-shot sysfs reads to 3 byte channel
This patch introduce num_data_channels variable on st_sensors struct
to manage different type of channels (size or number) in
st_sensors_get_buffer_element function.
Removed ST_SENSORS_NUMBER_DATA_CHANNELS and ST_SENSORS_BYTE_FOR_CHANNEL
and used struct iio_chan_spec const *ch to catch data.
Added 3 byte channel data support on one-shot reads.
Signed-off-by: Denis Ciocca <denis.ciocca@st.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/accel/st_accel_core.c | 3 | ||||
-rw-r--r-- | drivers/iio/common/st_sensors/st_sensors_buffer.c | 61 | ||||
-rw-r--r-- | drivers/iio/common/st_sensors/st_sensors_core.c | 34 | ||||
-rw-r--r-- | drivers/iio/gyro/st_gyro_core.c | 3 | ||||
-rw-r--r-- | drivers/iio/magnetometer/st_magn_core.c | 3 |
5 files changed, 73 insertions, 31 deletions
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 40236d5d8753..4aec121261d7 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/iio/common/st_sensors.h> | 26 | #include <linux/iio/common/st_sensors.h> |
27 | #include "st_accel.h" | 27 | #include "st_accel.h" |
28 | 28 | ||
29 | #define ST_ACCEL_NUMBER_DATA_CHANNELS 3 | ||
30 | |||
29 | /* DEFAULT VALUE FOR SENSORS */ | 31 | /* DEFAULT VALUE FOR SENSORS */ |
30 | #define ST_ACCEL_DEFAULT_OUT_X_L_ADDR 0x28 | 32 | #define ST_ACCEL_DEFAULT_OUT_X_L_ADDR 0x28 |
31 | #define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR 0x2a | 33 | #define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR 0x2a |
@@ -454,6 +456,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev) | |||
454 | if (err < 0) | 456 | if (err < 0) |
455 | goto st_accel_common_probe_error; | 457 | goto st_accel_common_probe_error; |
456 | 458 | ||
459 | adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS; | ||
457 | adata->multiread_bit = adata->sensor->multi_read_bit; | 460 | adata->multiread_bit = adata->sensor->multi_read_bit; |
458 | indio_dev->channels = adata->sensor->ch; | 461 | indio_dev->channels = adata->sensor->ch; |
459 | indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; | 462 | indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; |
diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index 09b236d6ee89..71a2c5f63b9c 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c | |||
@@ -24,11 +24,20 @@ | |||
24 | 24 | ||
25 | int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) | 25 | int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) |
26 | { | 26 | { |
27 | u8 *addr; | ||
27 | int i, n = 0, len; | 28 | int i, n = 0, len; |
28 | u8 addr[ST_SENSORS_NUMBER_DATA_CHANNELS]; | ||
29 | struct st_sensor_data *sdata = iio_priv(indio_dev); | 29 | struct st_sensor_data *sdata = iio_priv(indio_dev); |
30 | unsigned int num_data_channels = sdata->num_data_channels; | ||
31 | unsigned int byte_for_channel = | ||
32 | indio_dev->channels[0].scan_type.storagebits >> 3; | ||
30 | 33 | ||
31 | for (i = 0; i < ST_SENSORS_NUMBER_DATA_CHANNELS; i++) { | 34 | addr = kmalloc(num_data_channels, GFP_KERNEL); |
35 | if (!addr) { | ||
36 | len = -ENOMEM; | ||
37 | goto st_sensors_get_buffer_element_error; | ||
38 | } | ||
39 | |||
40 | for (i = 0; i < num_data_channels; i++) { | ||
32 | if (test_bit(i, indio_dev->active_scan_mask)) { | 41 | if (test_bit(i, indio_dev->active_scan_mask)) { |
33 | addr[n] = indio_dev->channels[i].address; | 42 | addr[n] = indio_dev->channels[i].address; |
34 | n++; | 43 | n++; |
@@ -37,52 +46,58 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) | |||
37 | switch (n) { | 46 | switch (n) { |
38 | case 1: | 47 | case 1: |
39 | len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, | 48 | len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, |
40 | addr[0], ST_SENSORS_BYTE_FOR_CHANNEL, buf, | 49 | addr[0], byte_for_channel, buf, sdata->multiread_bit); |
41 | sdata->multiread_bit); | ||
42 | break; | 50 | break; |
43 | case 2: | 51 | case 2: |
44 | if ((addr[1] - addr[0]) == ST_SENSORS_BYTE_FOR_CHANNEL) { | 52 | if ((addr[1] - addr[0]) == byte_for_channel) { |
45 | len = sdata->tf->read_multiple_byte(&sdata->tb, | 53 | len = sdata->tf->read_multiple_byte(&sdata->tb, |
46 | sdata->dev, addr[0], | 54 | sdata->dev, addr[0], byte_for_channel * n, |
47 | ST_SENSORS_BYTE_FOR_CHANNEL*n, | 55 | buf, sdata->multiread_bit); |
48 | buf, sdata->multiread_bit); | ||
49 | } else { | 56 | } else { |
50 | u8 rx_array[ST_SENSORS_BYTE_FOR_CHANNEL* | 57 | u8 *rx_array; |
51 | ST_SENSORS_NUMBER_DATA_CHANNELS]; | 58 | rx_array = kmalloc(byte_for_channel * num_data_channels, |
59 | GFP_KERNEL); | ||
60 | if (!rx_array) { | ||
61 | len = -ENOMEM; | ||
62 | goto st_sensors_free_memory; | ||
63 | } | ||
64 | |||
52 | len = sdata->tf->read_multiple_byte(&sdata->tb, | 65 | len = sdata->tf->read_multiple_byte(&sdata->tb, |
53 | sdata->dev, addr[0], | 66 | sdata->dev, addr[0], |
54 | ST_SENSORS_BYTE_FOR_CHANNEL* | 67 | byte_for_channel * num_data_channels, |
55 | ST_SENSORS_NUMBER_DATA_CHANNELS, | ||
56 | rx_array, sdata->multiread_bit); | 68 | rx_array, sdata->multiread_bit); |
57 | if (len < 0) | 69 | if (len < 0) { |
58 | goto read_data_channels_error; | 70 | kfree(rx_array); |
71 | goto st_sensors_free_memory; | ||
72 | } | ||
59 | 73 | ||
60 | for (i = 0; i < n * ST_SENSORS_NUMBER_DATA_CHANNELS; | 74 | for (i = 0; i < n * num_data_channels; i++) { |
61 | i++) { | ||
62 | if (i < n) | 75 | if (i < n) |
63 | buf[i] = rx_array[i]; | 76 | buf[i] = rx_array[i]; |
64 | else | 77 | else |
65 | buf[i] = rx_array[n + i]; | 78 | buf[i] = rx_array[n + i]; |
66 | } | 79 | } |
67 | len = ST_SENSORS_BYTE_FOR_CHANNEL*n; | 80 | kfree(rx_array); |
81 | len = byte_for_channel * n; | ||
68 | } | 82 | } |
69 | break; | 83 | break; |
70 | case 3: | 84 | case 3: |
71 | len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, | 85 | len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, |
72 | addr[0], ST_SENSORS_BYTE_FOR_CHANNEL* | 86 | addr[0], byte_for_channel * num_data_channels, |
73 | ST_SENSORS_NUMBER_DATA_CHANNELS, | ||
74 | buf, sdata->multiread_bit); | 87 | buf, sdata->multiread_bit); |
75 | break; | 88 | break; |
76 | default: | 89 | default: |
77 | len = -EINVAL; | 90 | len = -EINVAL; |
78 | goto read_data_channels_error; | 91 | goto st_sensors_free_memory; |
79 | } | 92 | } |
80 | if (len != ST_SENSORS_BYTE_FOR_CHANNEL*n) { | 93 | if (len != byte_for_channel * n) { |
81 | len = -EIO; | 94 | len = -EIO; |
82 | goto read_data_channels_error; | 95 | goto st_sensors_free_memory; |
83 | } | 96 | } |
84 | 97 | ||
85 | read_data_channels_error: | 98 | st_sensors_free_memory: |
99 | kfree(addr); | ||
100 | st_sensors_get_buffer_element_error: | ||
86 | return len; | 101 | return len; |
87 | } | 102 | } |
88 | EXPORT_SYMBOL(st_sensors_get_buffer_element); | 103 | EXPORT_SYMBOL(st_sensors_get_buffer_element); |
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index ed9bc8ae9330..865b1781df66 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c | |||
@@ -20,6 +20,11 @@ | |||
20 | 20 | ||
21 | #define ST_SENSORS_WAI_ADDRESS 0x0f | 21 | #define ST_SENSORS_WAI_ADDRESS 0x0f |
22 | 22 | ||
23 | static inline u32 st_sensors_get_unaligned_le24(const u8 *p) | ||
24 | { | ||
25 | return ((s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8); | ||
26 | } | ||
27 | |||
23 | static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev, | 28 | static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev, |
24 | u8 reg_addr, u8 mask, u8 data) | 29 | u8 reg_addr, u8 mask, u8 data) |
25 | { | 30 | { |
@@ -112,7 +117,8 @@ st_sensors_match_odr_error: | |||
112 | return ret; | 117 | return ret; |
113 | } | 118 | } |
114 | 119 | ||
115 | static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) | 120 | static int st_sensors_set_fullscale(struct iio_dev *indio_dev, |
121 | unsigned int fs) | ||
116 | { | 122 | { |
117 | int err, i = 0; | 123 | int err, i = 0; |
118 | struct st_sensor_data *sdata = iio_priv(indio_dev); | 124 | struct st_sensor_data *sdata = iio_priv(indio_dev); |
@@ -273,21 +279,33 @@ st_sensors_match_scale_error: | |||
273 | EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain); | 279 | EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain); |
274 | 280 | ||
275 | static int st_sensors_read_axis_data(struct iio_dev *indio_dev, | 281 | static int st_sensors_read_axis_data(struct iio_dev *indio_dev, |
276 | u8 ch_addr, int *data) | 282 | struct iio_chan_spec const *ch, int *data) |
277 | { | 283 | { |
278 | int err; | 284 | int err; |
279 | u8 outdata[ST_SENSORS_BYTE_FOR_CHANNEL]; | 285 | u8 *outdata; |
280 | struct st_sensor_data *sdata = iio_priv(indio_dev); | 286 | struct st_sensor_data *sdata = iio_priv(indio_dev); |
287 | unsigned int byte_for_channel = ch->scan_type.storagebits >> 3; | ||
288 | |||
289 | outdata = kmalloc(byte_for_channel, GFP_KERNEL); | ||
290 | if (!outdata) { | ||
291 | err = -EINVAL; | ||
292 | goto st_sensors_read_axis_data_error; | ||
293 | } | ||
281 | 294 | ||
282 | err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, | 295 | err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, |
283 | ch_addr, ST_SENSORS_BYTE_FOR_CHANNEL, | 296 | ch->address, byte_for_channel, |
284 | outdata, sdata->multiread_bit); | 297 | outdata, sdata->multiread_bit); |
285 | if (err < 0) | 298 | if (err < 0) |
286 | goto read_error; | 299 | goto st_sensors_free_memory; |
287 | 300 | ||
288 | *data = (s16)get_unaligned_le16(outdata); | 301 | if (byte_for_channel == 2) |
302 | *data = (s16)get_unaligned_le16(outdata); | ||
303 | else if (byte_for_channel == 3) | ||
304 | *data = (s32)st_sensors_get_unaligned_le24(outdata); | ||
289 | 305 | ||
290 | read_error: | 306 | st_sensors_free_memory: |
307 | kfree(outdata); | ||
308 | st_sensors_read_axis_data_error: | ||
291 | return err; | 309 | return err; |
292 | } | 310 | } |
293 | 311 | ||
@@ -307,7 +325,7 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, | |||
307 | goto read_error; | 325 | goto read_error; |
308 | 326 | ||
309 | msleep((sdata->sensor->bootime * 1000) / sdata->odr); | 327 | msleep((sdata->sensor->bootime * 1000) / sdata->odr); |
310 | err = st_sensors_read_axis_data(indio_dev, ch->address, val); | 328 | err = st_sensors_read_axis_data(indio_dev, ch, val); |
311 | if (err < 0) | 329 | if (err < 0) |
312 | goto read_error; | 330 | goto read_error; |
313 | 331 | ||
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index 9bae46bcccee..f9ed3488c314 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/iio/common/st_sensors.h> | 27 | #include <linux/iio/common/st_sensors.h> |
28 | #include "st_gyro.h" | 28 | #include "st_gyro.h" |
29 | 29 | ||
30 | #define ST_GYRO_NUMBER_DATA_CHANNELS 3 | ||
31 | |||
30 | /* DEFAULT VALUE FOR SENSORS */ | 32 | /* DEFAULT VALUE FOR SENSORS */ |
31 | #define ST_GYRO_DEFAULT_OUT_X_L_ADDR 0x28 | 33 | #define ST_GYRO_DEFAULT_OUT_X_L_ADDR 0x28 |
32 | #define ST_GYRO_DEFAULT_OUT_Y_L_ADDR 0x2a | 34 | #define ST_GYRO_DEFAULT_OUT_Y_L_ADDR 0x2a |
@@ -313,6 +315,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev) | |||
313 | if (err < 0) | 315 | if (err < 0) |
314 | goto st_gyro_common_probe_error; | 316 | goto st_gyro_common_probe_error; |
315 | 317 | ||
318 | gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS; | ||
316 | gdata->multiread_bit = gdata->sensor->multi_read_bit; | 319 | gdata->multiread_bit = gdata->sensor->multi_read_bit; |
317 | indio_dev->channels = gdata->sensor->ch; | 320 | indio_dev->channels = gdata->sensor->ch; |
318 | indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; | 321 | indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; |
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 715d61681df3..ebfe8f11a0c2 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/iio/common/st_sensors.h> | 26 | #include <linux/iio/common/st_sensors.h> |
27 | #include "st_magn.h" | 27 | #include "st_magn.h" |
28 | 28 | ||
29 | #define ST_MAGN_NUMBER_DATA_CHANNELS 3 | ||
30 | |||
29 | /* DEFAULT VALUE FOR SENSORS */ | 31 | /* DEFAULT VALUE FOR SENSORS */ |
30 | #define ST_MAGN_DEFAULT_OUT_X_L_ADDR 0X04 | 32 | #define ST_MAGN_DEFAULT_OUT_X_L_ADDR 0X04 |
31 | #define ST_MAGN_DEFAULT_OUT_Y_L_ADDR 0X08 | 33 | #define ST_MAGN_DEFAULT_OUT_Y_L_ADDR 0X08 |
@@ -356,6 +358,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev) | |||
356 | if (err < 0) | 358 | if (err < 0) |
357 | goto st_magn_common_probe_error; | 359 | goto st_magn_common_probe_error; |
358 | 360 | ||
361 | mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS; | ||
359 | mdata->multiread_bit = mdata->sensor->multi_read_bit; | 362 | mdata->multiread_bit = mdata->sensor->multi_read_bit; |
360 | indio_dev->channels = mdata->sensor->ch; | 363 | indio_dev->channels = mdata->sensor->ch; |
361 | indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; | 364 | indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; |