diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 index 33e96f740639..147d4e8a1403 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 +++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 @@ -14,3 +14,11 @@ Description: Show or set the gain boost of the amp, from 0-31 range. 18 = indoors (default) 14 = outdoors + +What /sys/bus/iio/devices/iio:deviceX/noise_level_tripped +Date: May 2017 +KernelVersion: 4.13 +Contact: Matt Ranostay +Description: + When 1 the noise level is over the trip level and not reporting + valid data diff --git a/Documentation/devicetree/bindings/iio/proximity/as3935.txt b/Documentation/devicetree/bindings/iio/proximity/as3935.txt index 38d74314b7ab..b6c1afa6f02d 100644 --- a/Documentation/devicetree/bindings/iio/proximity/as3935.txt +++ b/Documentation/devicetree/bindings/iio/proximity/as3935.txt @@ -16,6 +16,10 @@ Optional properties: - ams,tuning-capacitor-pf: Calibration tuning capacitor stepping value 0 - 120pF. This will require using the calibration data from the manufacturer. + - ams,nflwdth: Set the noise and watchdog threshold register on + startup. This will need to set according to the noise from the + MCU board, and possibly the local environment. Refer to the + datasheet for the threshold settings. Example: @@ -27,4 +31,5 @@ as3935@0 { interrupt-parent = <&gpio1>; interrupts = <16 1>; ams,tuning-capacitor-pf = <80>; + ams,nflwdth = <0x44>; }; diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 57625653fcb6..1d13bf03c758 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -243,6 +243,8 @@ config DA9150_GPADC config DLN2_ADC tristate "Diolan DLN-2 ADC driver support" depends on MFD_DLN2 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Diolan DLN-2 ADC. diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index bc5b38e3a147..a70ef7fec95f 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -225,6 +225,7 @@ struct at91_adc_trigger { char *name; unsigned int trgmod_value; unsigned int edge_type; + bool hw_trig; }; struct at91_adc_state { @@ -254,16 +255,25 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = { .name = "external_rising", .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE, .edge_type = IRQ_TYPE_EDGE_RISING, + .hw_trig = true, }, { .name = "external_falling", .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL, .edge_type = IRQ_TYPE_EDGE_FALLING, + .hw_trig = true, }, { .name = "external_any", .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY, .edge_type = IRQ_TYPE_EDGE_BOTH, + .hw_trig = true, + }, + { + .name = "software", + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER, + .edge_type = IRQ_TYPE_NONE, + .hw_trig = false, }, }; @@ -597,7 +607,7 @@ static int at91_adc_probe(struct platform_device *pdev) struct at91_adc_state *st; struct resource *res; int ret, i; - u32 edge_type; + u32 edge_type = IRQ_TYPE_NONE; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); if (!indio_dev) @@ -641,14 +651,14 @@ static int at91_adc_probe(struct platform_device *pdev) ret = of_property_read_u32(pdev->dev.of_node, "atmel,trigger-edge-type", &edge_type); if (ret) { - dev_err(&pdev->dev, - "invalid or missing value for atmel,trigger-edge-type\n"); - return ret; + dev_dbg(&pdev->dev, + "atmel,trigger-edge-type not specified, only software trigger available\n"); } st->selected_trig = NULL; - for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++) + /* find the right trigger, or no trigger at all */ + for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++) if (at91_adc_trigger_list[i].edge_type == edge_type) { st->selected_trig = &at91_adc_trigger_list[i]; break; @@ -717,24 +727,27 @@ static int at91_adc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); - ret = at91_adc_buffer_init(indio_dev); - if (ret < 0) { - dev_err(&pdev->dev, "couldn't initialize the buffer.\n"); - goto per_clk_disable_unprepare; - } + if (st->selected_trig->hw_trig) { + ret = at91_adc_buffer_init(indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "couldn't initialize the buffer.\n"); + goto per_clk_disable_unprepare; + } - ret = at91_adc_trigger_init(indio_dev); - if (ret < 0) { - dev_err(&pdev->dev, "couldn't setup the triggers.\n"); - goto per_clk_disable_unprepare; + ret = at91_adc_trigger_init(indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "couldn't setup the triggers.\n"); + goto per_clk_disable_unprepare; + } } ret = iio_device_register(indio_dev); if (ret < 0) goto per_clk_disable_unprepare; - dev_info(&pdev->dev, "setting up trigger as %s\n", - st->selected_trig->name); + if (st->selected_trig->hw_trig) + dev_info(&pdev->dev, "setting up trigger as %s\n", + st->selected_trig->name); dev_info(&pdev->dev, "version: %x\n", readl_relaxed(st->base + AT91_SAMA5D2_VERSION)); diff --git a/drivers/iio/dummy/iio_simple_dummy_events.c b/drivers/iio/dummy/iio_simple_dummy_events.c index ed63ffd849f8..7ec2a0bb0807 100644 --- a/drivers/iio/dummy/iio_simple_dummy_events.c +++ b/drivers/iio/dummy/iio_simple_dummy_events.c @@ -72,6 +72,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev, st->event_en = state; else return -EINVAL; + break; default: return -EINVAL; } diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index ebfb1de7377f..91431454eb85 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -865,7 +865,6 @@ complete: static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, struct zpa2326_private *private) { - int ret; unsigned int val; long timeout; @@ -887,14 +886,11 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, /* Timed out. */ zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)", timeout); - ret = -ETIME; - } else if (timeout < 0) { - zpa2326_warn(indio_dev, - "wait for one shot interrupt cancelled"); - ret = -ERESTARTSYS; + return -ETIME; } - return ret; + zpa2326_warn(indio_dev, "wait for one shot interrupt cancelled"); + return -ERESTARTSYS; } static int zpa2326_init_managed_irq(struct device *parent, diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index 0eeff29b61be..4a48b7ba3a1c 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -39,8 +39,12 @@ #define AS3935_AFE_GAIN_MAX 0x1F #define AS3935_AFE_PWR_BIT BIT(0) +#define AS3935_NFLWDTH 0x01 +#define AS3935_NFLWDTH_MASK 0x7f + #define AS3935_INT 0x03 #define AS3935_INT_MASK 0x0f +#define AS3935_DISTURB_INT BIT(2) #define AS3935_EVENT_INT BIT(3) #define AS3935_NOISE_INT BIT(0) @@ -48,6 +52,7 @@ #define AS3935_DATA_MASK 0x3F #define AS3935_TUNE_CAP 0x08 +#define AS3935_DEFAULTS 0x3C #define AS3935_CALIBRATE 0x3D #define AS3935_READ_DATA BIT(14) @@ -62,7 +67,9 @@ struct as3935_state { struct mutex lock; struct delayed_work work; + unsigned long noise_tripped; u32 tune_cap; + u32 nflwdth_reg; u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */ u8 buf[2] ____cacheline_aligned; }; @@ -145,12 +152,29 @@ static ssize_t as3935_sensor_sensitivity_store(struct device *dev, return len; } +static ssize_t as3935_noise_level_tripped_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct as3935_state *st = iio_priv(dev_to_iio_dev(dev)); + int ret; + + mutex_lock(&st->lock); + ret = sprintf(buf, "%d\n", !time_after(jiffies, st->noise_tripped + HZ)); + mutex_unlock(&st->lock); + + return ret; +} + static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR, as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0); +static IIO_DEVICE_ATTR(noise_level_tripped, S_IRUGO, + as3935_noise_level_tripped_show, NULL, 0); static struct attribute *as3935_attributes[] = { &iio_dev_attr_sensor_sensitivity.dev_attr.attr, + &iio_dev_attr_noise_level_tripped.dev_attr.attr, NULL, }; @@ -246,7 +270,11 @@ static void as3935_event_work(struct work_struct *work) case AS3935_EVENT_INT: iio_trigger_poll_chained(st->trig); break; + case AS3935_DISTURB_INT: case AS3935_NOISE_INT: + mutex_lock(&st->lock); + st->noise_tripped = jiffies; + mutex_unlock(&st->lock); dev_warn(&st->spi->dev, "noise level is too high\n"); break; } @@ -269,15 +297,14 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private) static void calibrate_as3935(struct as3935_state *st) { - /* mask disturber interrupt bit */ - as3935_write(st, AS3935_INT, BIT(5)); - + as3935_write(st, AS3935_DEFAULTS, 0x96); as3935_write(st, AS3935_CALIBRATE, 0x96); as3935_write(st, AS3935_TUNE_CAP, BIT(5) | (st->tune_cap / TUNE_CAP_DIV)); mdelay(2); as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV)); + as3935_write(st, AS3935_NFLWDTH, st->nflwdth_reg); } #ifdef CONFIG_PM_SLEEP @@ -370,6 +397,15 @@ static int as3935_probe(struct spi_device *spi) return -EINVAL; } + ret = of_property_read_u32(np, + "ams,nflwdth", &st->nflwdth_reg); + if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) { + dev_err(&spi->dev, + "invalid nflwdth setting of %d\n", + st->nflwdth_reg); + return -EINVAL; + } + indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->channels = as3935_channels; @@ -384,6 +420,7 @@ static int as3935_probe(struct spi_device *spi) return -ENOMEM; st->trig = trig; + st->noise_tripped = jiffies - HZ; trig->dev.parent = indio_dev->dev.parent; iio_trigger_set_drvdata(trig, indio_dev); trig->ops = &iio_interrupt_trigger_ops; diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 1691760339da..02573c517d9d 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -172,7 +172,7 @@ static int ade7759_spi_read_reg_40(struct device *dev, reg_address); goto error_ret; } - *val = ((u64)st->rx[1] << 32) | (st->rx[2] << 24) | + *val = ((u64)st->rx[1] << 32) | ((u64)st->rx[2] << 24) | (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5]; error_ret: diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 5f3d8f2339e3..4be864dbd41c 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream __func__, instance); instance->alsa_stream = alsa_stream; alsa_stream->instance = instance; - ret = 0; // xxx todo -1; - goto err_free_mem; + return 0; } /* Initialize and create a VCHI connection */ @@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", __func__, ret); - ret = -EIO; - goto err_free_mem; + return -EIO; } ret = vchi_connect(NULL, 0, vchi_instance); if (ret) { LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", __func__, ret); - ret = -EIO; - goto err_free_mem; + kfree(vchi_instance); + return -EIO; } initted = 1; } @@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream if (IS_ERR(instance)) { LOG_ERR("%s: failed to initialize audio service\n", __func__); - ret = PTR_ERR(instance); - goto err_free_mem; + /* vchi_instance is retained for use the next time. */ + return PTR_ERR(instance); } instance->alsa_stream = alsa_stream; alsa_stream->instance = instance; LOG_DBG(" success !\n"); - ret = 0; -err_free_mem: - kfree(vchi_instance); - return ret; + return 0; } int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)