Lines Matching +full:iio +full:- +full:aux
1 // SPDX-License-Identifier: GPL-2.0-only
3 * si1145.c - Support for Silabs SI1132 and SI1141/2/3/5/6/7 combined ambient
6 * Copyright 2014-16 Peter Meerwald-Stadler <pmeerw@pmeerw.net>
9 * SI1132 (7-bit I2C slave address 0x60)
10 * SI1141/2/3 (7-bit I2C slave address 0x5a)
11 * SI1145/6/6 (7-bit I2C slave address 0x60)
21 #include <linux/iio/iio.h>
22 #include <linux/iio/sysfs.h>
23 #include <linux/iio/trigger.h>
24 #include <linux/iio/trigger_consumer.h>
25 #include <linux/iio/triggered_buffer.h>
26 #include <linux/iio/buffer.h>
125 /* Return -ETIMEDOUT after this long */
161 * struct si1145_data - si1145 chip state data
164 * @cmdlock: Low-level mutex to protect command execution only
165 * @rsp_seq: Next expected response number or -1 if counter reset required
169 * @trig: Pointer to iio trigger
194 * __si1145_command_reset() - Send CMD_NOP and wait for response 0
196 * Does not modify data->rsp_seq
198 * Return: 0 on success and -errno on error.
202 struct device *dev = &data->client->dev; in __si1145_command_reset()
206 ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND, in __si1145_command_reset()
214 ret = i2c_smbus_read_byte_data(data->client, in __si1145_command_reset()
220 return -ETIMEDOUT; in __si1145_command_reset()
227 * si1145_command() - Execute a command and poll the response register
229 * All conversion overflows are reported as -EOVERFLOW
230 * INVALID_SETTING is reported as -EINVAL
231 * Timeouts are reported as -ETIMEDOUT
233 * Return: 0 on success or -errno on failure
237 struct device *dev = &data->client->dev; in si1145_command()
241 mutex_lock(&data->cmdlock); in si1145_command()
243 if (data->rsp_seq < 0) { in si1145_command()
250 data->rsp_seq = 0; in si1145_command()
253 ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND, cmd); in si1145_command()
263 ret = i2c_smbus_read_byte_data(data->client, in si1145_command()
271 if (ret == data->rsp_seq) { in si1145_command()
275 ret = -ETIMEDOUT; in si1145_command()
281 if (ret == ((data->rsp_seq + 1) & in si1145_command()
283 data->rsp_seq = ret; in si1145_command()
288 ret, (data->rsp_seq + 1) & in si1145_command()
290 ret = -EIO; in si1145_command()
295 ret = -EINVAL; in si1145_command()
300 ret = -EOVERFLOW; in si1145_command()
305 data->rsp_seq = -1; in si1145_command()
310 mutex_unlock(&data->cmdlock); in si1145_command()
320 ret = i2c_smbus_write_byte_data(data->client, in si1145_param_update()
342 return i2c_smbus_read_byte_data(data->client, SI1145_REG_PARAM_RD); in si1145_param_query()
358 return result << (exponent - 4); in si1145_uncompress()
359 return result >> (4 - exponent); in si1145_uncompress()
382 significand = x << (4 - exponent); in si1145_compress()
386 significand = x >> (exponent - 5); in si1145_compress()
401 if (data->part_info->uncompressed_meas_rate) in si1145_set_meas_rate()
402 return i2c_smbus_write_word_data(data->client, in si1145_set_meas_rate()
405 return i2c_smbus_write_byte_data(data->client, in si1145_set_meas_rate()
412 if (data->part_info->uncompressed_meas_rate) in si1145_read_samp_freq()
413 *val2 = data->meas_rate; in si1145_read_samp_freq()
415 *val2 = si1145_uncompress(data->meas_rate); in si1145_read_samp_freq()
426 return -ERANGE; in si1145_store_samp_freq()
429 mutex_lock(&data->lock); in si1145_store_samp_freq()
430 if (data->autonomous) { in si1145_store_samp_freq()
435 if (data->part_info->uncompressed_meas_rate) in si1145_store_samp_freq()
436 data->meas_rate = meas_rate; in si1145_store_samp_freq()
438 data->meas_rate = si1145_compress(meas_rate); in si1145_store_samp_freq()
441 mutex_unlock(&data->lock); in si1145_store_samp_freq()
449 struct iio_dev *indio_dev = pf->indio_dev; in si1145_trigger_handler()
455 if (!data->autonomous) { in si1145_trigger_handler()
457 if (ret < 0 && ret != -EOVERFLOW) in si1145_trigger_handler()
460 irq_status = ret = i2c_smbus_read_byte_data(data->client, in si1145_trigger_handler()
472 if (!test_bit(i + run, indio_dev->active_scan_mask)) in si1145_trigger_handler()
474 if (indio_dev->channels[i + run].address != in si1145_trigger_handler()
475 indio_dev->channels[i].address + 2 * run) in si1145_trigger_handler()
481 data->client, indio_dev->channels[i].address, in si1145_trigger_handler()
482 sizeof(u16) * run, &data->buffer[j]); in si1145_trigger_handler()
486 i += run - 1; in si1145_trigger_handler()
489 if (data->autonomous) { in si1145_trigger_handler()
490 ret = i2c_smbus_write_byte_data(data->client, in si1145_trigger_handler()
497 iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, in si1145_trigger_handler()
501 iio_trigger_notify_done(indio_dev->trig); in si1145_trigger_handler()
513 if (data->scan_mask == scan_mask) in si1145_set_chlist()
517 switch (indio_dev->channels[i].address) { in si1145_set_chlist()
534 switch (indio_dev->channels[i].type) { in si1145_set_chlist()
540 if (indio_dev->channels[i].type == IIO_TEMP) in si1145_set_chlist()
554 data->scan_mask = scan_mask; in si1145_set_chlist()
567 ret = si1145_set_chlist(indio_dev, BIT(chan->scan_index)); in si1145_measure()
571 cmd = (chan->type == IIO_PROXIMITY) ? SI1145_CMD_PS_FORCE : in si1145_measure()
574 if (ret < 0 && ret != -EOVERFLOW) in si1145_measure()
577 return i2c_smbus_read_word_data(data->client, chan->address); in si1145_measure()
581 * Conversion between iio scale and ADC_GAIN values
605 return -EINVAL; in si1145_proximity_adcgain_from_scale()
615 return -EINVAL; in si1145_intensity_adcgain_from_scale()
630 switch (chan->type) { in si1145_read_raw()
649 ret = i2c_smbus_read_byte_data(data->client, in si1145_read_raw()
650 SI1145_PS_LED_REG(chan->channel)); in si1145_read_raw()
654 *val = (ret >> SI1145_PS_LED_SHIFT(chan->channel)) in si1145_read_raw()
659 return -EINVAL; in si1145_read_raw()
662 switch (chan->type) { in si1145_read_raw()
667 if (chan->channel2 == IIO_MOD_LIGHT_IR) in si1145_read_raw()
681 return -EINVAL; in si1145_read_raw()
692 switch (chan->type) { in si1145_read_raw()
695 * -ADC offset - ADC counts @ 25°C - in si1145_read_raw()
698 *val = -256 - 11136 + 25 * 35; in si1145_read_raw()
703 * by -256 in si1145_read_raw()
709 *val = -si1145_uncompress(ret); in si1145_read_raw()
715 return -EINVAL; in si1145_read_raw()
729 switch (chan->type) { in si1145_write_raw()
741 if (chan->channel2 == IIO_MOD_LIGHT_IR) { in si1145_write_raw()
750 return -EINVAL; in si1145_write_raw()
767 if (chan->type != IIO_CURRENT) in si1145_write_raw()
768 return -EINVAL; in si1145_write_raw()
771 return -EINVAL; in si1145_write_raw()
773 reg1 = SI1145_PS_LED_REG(chan->channel); in si1145_write_raw()
774 shift = SI1145_PS_LED_SHIFT(chan->channel); in si1145_write_raw()
780 ret = i2c_smbus_read_byte_data(data->client, reg1); in si1145_write_raw()
785 ret = i2c_smbus_write_byte_data(data->client, reg1, in si1145_write_raw()
793 return -EINVAL; in si1145_write_raw()
876 .scan_index = -1, \
1013 struct i2c_client *client = data->client; in si1145_initialize()
1039 switch (data->part_info->num_leds) { in si1145_initialize()
1114 if (data->part_info == &si1145_part_info[SI1132] || in si1145_initialize()
1115 data->part_info == &si1145_part_info[SI1145] || in si1145_initialize()
1116 data->part_info == &si1145_part_info[SI1146] || in si1145_initialize()
1117 data->part_info == &si1145_part_info[SI1147]) { in si1145_initialize()
1118 ret = i2c_smbus_write_byte_data(data->client, in si1145_initialize()
1123 ret = i2c_smbus_write_byte_data(data->client, in si1145_initialize()
1127 ret = i2c_smbus_write_byte_data(data->client, in si1145_initialize()
1131 ret = i2c_smbus_write_byte_data(data->client, in si1145_initialize()
1150 mutex_lock(&data->lock); in si1145_buffer_preenable()
1151 ret = si1145_set_chlist(indio_dev, *indio_dev->active_scan_mask); in si1145_buffer_preenable()
1152 mutex_unlock(&data->lock); in si1145_buffer_preenable()
1164 /* Check that at most one AUX channel is enabled */ in si1145_validate_scan_mask()
1165 for_each_set_bit(i, scan_mask, data->part_info->num_channels) { in si1145_validate_scan_mask()
1166 if (indio_dev->channels[i].address == SI1145_REG_AUX_DATA) in si1145_validate_scan_mask()
1179 * si1145_trigger_set_state() - Set trigger state
1190 mutex_lock(&data->lock); in si1145_trigger_set_state()
1193 data->autonomous = true; in si1145_trigger_set_state()
1194 err = i2c_smbus_write_byte_data(data->client, in si1145_trigger_set_state()
1198 err = i2c_smbus_write_byte_data(data->client, in si1145_trigger_set_state()
1202 err = si1145_set_meas_rate(data, data->meas_rate); in si1145_trigger_set_state()
1217 ret = i2c_smbus_write_byte_data(data->client, in si1145_trigger_set_state()
1221 ret = i2c_smbus_write_byte_data(data->client, in si1145_trigger_set_state()
1225 data->autonomous = false; in si1145_trigger_set_state()
1228 mutex_unlock(&data->lock); in si1145_trigger_set_state()
1239 struct i2c_client *client = data->client; in si1145_probe_trigger()
1243 trig = devm_iio_trigger_alloc(&client->dev, in si1145_probe_trigger()
1244 "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); in si1145_probe_trigger()
1246 return -ENOMEM; in si1145_probe_trigger()
1248 trig->ops = &si1145_trigger_ops; in si1145_probe_trigger()
1251 ret = devm_request_irq(&client->dev, client->irq, in si1145_probe_trigger()
1257 dev_err(&client->dev, "irq request failed\n"); in si1145_probe_trigger()
1261 ret = devm_iio_trigger_register(&client->dev, trig); in si1145_probe_trigger()
1265 data->trig = trig; in si1145_probe_trigger()
1266 indio_dev->trig = iio_trigger_get(data->trig); in si1145_probe_trigger()
1279 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); in si1145_probe()
1281 return -ENOMEM; in si1145_probe()
1285 data->client = client; in si1145_probe()
1286 data->part_info = &si1145_part_info[id->driver_data]; in si1145_probe()
1288 part_id = ret = i2c_smbus_read_byte_data(data->client, in si1145_probe()
1292 rev_id = ret = i2c_smbus_read_byte_data(data->client, in si1145_probe()
1296 seq_id = ret = i2c_smbus_read_byte_data(data->client, in si1145_probe()
1300 dev_info(&client->dev, "device ID part 0x%02x rev 0x%02x seq 0x%02x\n", in si1145_probe()
1302 if (part_id != data->part_info->part) { in si1145_probe()
1303 dev_err(&client->dev, "part ID mismatch got 0x%02x, expected 0x%02x\n", in si1145_probe()
1304 part_id, data->part_info->part); in si1145_probe()
1305 return -ENODEV; in si1145_probe()
1308 indio_dev->name = id->name; in si1145_probe()
1309 indio_dev->channels = data->part_info->channels; in si1145_probe()
1310 indio_dev->num_channels = data->part_info->num_channels; in si1145_probe()
1311 indio_dev->info = data->part_info->iio_info; in si1145_probe()
1312 indio_dev->modes = INDIO_DIRECT_MODE; in si1145_probe()
1314 mutex_init(&data->lock); in si1145_probe()
1315 mutex_init(&data->cmdlock); in si1145_probe()
1321 ret = devm_iio_triggered_buffer_setup(&client->dev, in si1145_probe()
1327 if (client->irq) { in si1145_probe()
1332 dev_info(&client->dev, "no irq, using polling\n"); in si1145_probe()
1335 return devm_iio_device_register(&client->dev, indio_dev); in si1145_probe()
1360 MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");