= TSL2591_DEFAULT_ALS_INT_TIME;
> + chip->als_settings.als_gain = TSL2591_DEFAULT_ALS_GAIN;
> + chip->als_settings.als_persist = TSL2591_DEFAULT_ALS_PERSIST;
> + chip->als_settings.als_lower_threshold =
> + TSL2591_DEFAULT_ALS_LOWER_THRESHOLD;
> + chip->als_setti
te_raw(struct iio_dev *indio_dev,
> > + struct iio_chan_spec const *chan, int val, int val2,
> > + long mask)
> > +{
> > + int ret;
> > + struct bma400_data *data = iio_priv(indio_dev);
> > +
> > + switch (mask) {
> > + case IIO_CHAN_INFO_SAMP_FREQ:
> > + /*
> > +* The sample frequency is readonly for the temperature
> > +* register and a fixed value in low-power mode.
> > +*/
> > + if (chan->type != IIO_ACCEL)
> > + return -EINVAL;
> > +
> > + mutex_lock(>mutex);
> > + ret = bma400_set_accel_output_data_rate(data, val, val2);
> > + mutex_unlock(>mutex);
> > + return ret;
> > + case IIO_CHAN_INFO_SCALE:
> > + if (val != 0)
> > + return -EINVAL;
> > +
> > + mutex_lock(>mutex);
> > + ret = bma400_set_accel_scale(data, val2);
> > + mutex_unlock(>mutex);
> > + return ret;
> > + case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> > + mutex_lock(>mutex);
> > + ret = bma400_set_accel_oversampling_ratio(data, val);
> > + mutex_unlock(>mutex);
> > + return ret;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > +
> > +static int bma400_write_raw_get_fmt(struct iio_dev *indio_dev,
> > + struct iio_chan_spec const *chan,
> > + long mask)
> > +{
> > + switch (mask) {
> > + case IIO_CHAN_INFO_SAMP_FREQ:
> > + return IIO_VAL_INT_PLUS_MICRO;
> > + case IIO_CHAN_INFO_SCALE:
> > + return IIO_VAL_INT_PLUS_MICRO;
> > + case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> > + return IIO_VAL_INT;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > +
> > +static const struct iio_info bma400_info = {
> > + .attrs = _attrs_group,
> > + .read_raw = bma400_read_raw,
> > + .write_raw = bma400_write_raw,
> > + .write_raw_get_fmt = bma400_write_raw_get_fmt,
> > +};
> > +
> > +int bma400_probe(struct device *dev,
> > +struct regmap *regmap,
> > +const char *name)
> > +{
> > + int ret;
> > + struct bma400_data *data;
> > + struct iio_dev *indio_dev;
> > +
> > + indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> > + if (!indio_dev)
> > + return -ENOMEM;
> > +
> > + data = iio_priv(indio_dev);
> > + data->regmap = regmap;
> > + data->dev = dev;
> > +
> > + ret = bma400_init(data);
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = iio_read_mount_matrix(dev, "mount-matrix",
> > + >orientation);
>
> Looks like the above will fit on one line..
>
> > + if (ret)
> > + return ret;
> > +
> > + mutex_init(>mutex);
> > + indio_dev->dev.parent = dev;
> > + indio_dev->name = name;
> > + indio_dev->info = _info;
> > + indio_dev->channels = bma400_channels;
> > + indio_dev->num_channels = ARRAY_SIZE(bma400_channels);
> > + indio_dev->modes = INDIO_DIRECT_MODE;
> > +
> > + dev_set_drvdata(dev, indio_dev);
> > +
> > + ret = iio_device_register(indio_dev);
> > + if (ret < 0) {
> > + dev_err(dev, "unable to register iio device\n");
> > + return ret;
>
> Drop the return out of the if statement and no need for the return 0 below.
I'd also avoid the error message altogether
>
> > + }
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL(bma400_probe);
> > +
> > +int bma400_remove(struct device *dev)
> > +{
> > + int ret;
> > + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> > + struct bma400_data *data = iio_priv(indio_dev);
> > +
> > + mutex_lock(>mutex);
> > + ret = bma400_softreset(data);
> > + if (ret < 0) {
> > + /*
> > +* If the softreset failed, try to put the device in
> > +* sleep mode, but still report the error.
> > +*/
> > + dev_err(data->dev, "Failed to reset the device");
> > + bma400_set_power_mode(data, POWER_MODE_SLEEP);
> > + }
> > + mutex_unlock(>mutex);
> > +
> > + iio_device_unregister(indio_dev);
> > +
> > + return ret;
> > +}
> > +EXPORT_SYMBOL(bma400_remove);
> > +
> > +MODULE_AUTHOR("Dan Robertson ");
> > +MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c
> > new file mode 100644
> > index ..227012a32e13
> > --- /dev/null
> > +++ b/drivers/iio/accel/bma400_i2c.c
> > @@ -0,0 +1,54 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * bma400-i2c.c - I2C IIO driver for Bosch BMA400 triaxial acceleration
> > sensor.
> > + *
> > + * Copyright 2019 Dan Robertson
> > + *
> > + * I2C address is either 0x14 or 0x15 depending on SDO
> > + *
>
> This blank line doesn't add anything (nitpick)
>
> > + */
> > +#include
> > +#include
> > +#include
>
> Slight preference for alphabetical order. Also why ACPI?
>
> > +#include
> > +#include
> > +
> > +#include "bma400.h"
> > +
> > +static int bma400_i2c_probe(struct i2c_client *client,
> > + const struct i2c_device_id *id)
> > +{
> > + struct regmap *regmap;
> > +
> > + regmap = devm_regmap_init_i2c(client,
> > + _regmap_config);
> > +
> > + return bma400_probe(>dev, regmap, id->name);
> > +}
> > +
> > +static int bma400_i2c_remove(struct i2c_client *client)
> > +{
> > + return bma400_remove(>dev);
> > +}
> > +
> > +static const struct i2c_device_id bma400_i2c_ids[] = {
> > + { "bma400", 0 },
> > + { }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(i2c, bma400_i2c_ids);
> > +
>
> Good to have a of_device_id table as well from the start.
> There is a general (but slow) move to stop using the fallback
> to the i2c_device_id table.
>
> > +static struct i2c_driver bma400_i2c_driver = {
> > + .driver = {
> > + .name = "bma400",
> > + },
> > + .probe= bma400_i2c_probe,
> > + .remove = bma400_i2c_remove,
> > + .id_table = bma400_i2c_ids,
> > +};
> > +
> > +module_i2c_driver(bma400_i2c_driver);
> > +
> > +MODULE_AUTHOR("Dan Robertson ");
> > +MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor");
> > +MODULE_LICENSE("GPL");
> >
> >
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
ic const struct of_device_id max5432_dt_ids[] = {
> + { .compatible = "maxim,max5432", .data = (void *)OHM_50K },
> + { .compatible = "maxim,max5433", .data = (void *)OHM_100K },
> + { .compatible = "maxim,max5434", .data = (void *)OHM_50K },
> + { .compatible = "maxim,max5435", .data = (void *)OHM_100K },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, max5432_dt_ids);
> +
> +static struct i2c_driver max5432_driver = {
> + .driver = {
> + .name = "max5432",
> + .of_match_table = of_match_ptr(max5432_dt_ids),
> + },
> + .probe = max5432_probe,
> +};
> +
> +module_i2c_driver(max5432_driver);
> +
> +MODULE_AUTHOR("Martin Kaiser ");
> +MODULE_DESCRIPTION("max5432-max5435 digital potentiometers");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
+
> + /* Switch to bank0 (Magic number)*/
> + ret = regmap_write(data->regmap, 0x7F, 0x00);
maybe a #define for 0x7f, PAT9125_BANK_SWITCH_REG
> + if (ret < 0) {
> + dev_err(indio_dev->dev.parent, "register 0x%x access failed
> %d\n",
> + 0x7F, ret);
> + return ret;
> + }
> +
> + /* Software reset */
> + ret = regmap_write_bits(data->regmap,
> + PAT9125_CONFIG_REG,
> + PAT9125_RESET_BIT,
> + 1);
> + if (ret < 0) {
> + dev_err(>dev, "register 0x%x access failed %d\n",
> + PAT9125_CONFIG_REG, ret);
> + return ret;
> + }
> +
> + msleep(20);
> +
> + /* Init GPIO IRQ */
> + if (client->irq) {
> + ret = devm_request_threaded_irq(>dev,
> + client->irq,
> + NULL,
> + pat9125_threaded_event_handler,
> + IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> + "pat9125",
> + indio_dev);
> + if (ret) {
> + dev_err(>dev, "GPIO IRQ init failed\n");
> + return ret;
> + }
> + }
> +
> + ret = devm_iio_device_register(>dev, indio_dev);
> + if (ret) {
> + dev_err(>dev, "IIO device register failed\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id pat9125_id[] = {
> + { "pat9125", 0 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, pat9125_id);
> +
> +static const unsigned short normal_i2c[] = {
pat9125_ prefix please
> + PAT9125_I2C_ADDR_HI,
> + PAT9125_I2C_ADDR_LO,
> + PAT9125_I2C_ADDR_NC,
> + I2C_CLIENT_END
> +};
> +
> +static struct i2c_driver pat9125_driver = {
> + .driver = {
> + .name = "pat9125",
> + },
> + .probe = pat9125_probe,
> + .address_list = normal_i2c,
> + .id_table = pat9125_id,
> +};
> +
> +module_i2c_driver(pat9125_driver);
> +
> +MODULE_AUTHOR("Alexandre Mergnat ");
> +MODULE_DESCRIPTION("Optical Tracking sensor");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
t; + */
> + r = regmap_write(data->regmap, DPS310_PRS_CFG,
> + DPS310_CALC_RATE(1) | DPS310_CALC_PRC(1));
> +
> + /*
>* Set up external (MEMS) temperature sensor in single sample, one
>* measurement per second mode
>*/
> @@ -399,16 +667,23 @@ static int dps310_probe(struct i2c_client *client,
> if (r < 0)
> goto err;
>
> - /* Temp shift is disabled when PRC <= 8 */
> + /* Temp and pressure shifts are disabled when PRC <= 8 */
> r = regmap_write_bits(data->regmap, DPS310_CFG_REG,
> - DPS310_TMP_SHIFT_EN, 0);
> + DPS310_TMP_SHIFT_EN | DPS310_PRS_SHIFT_EN, 0);
> + if (r < 0)
> + goto err;
> +
> + /* MEAS_CFG doesn't seem to update unless first written with 0 */
> + r = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
> + DPS310_MEAS_CTRL_BITS, 0);
> if (r < 0)
> goto err;
>
> - /* Turn on temperature measurement in the background */
> + /* Turn on temperature and pressure measurement in the background */
> r = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
> DPS310_MEAS_CTRL_BITS,
> - DPS310_TEMP_EN | DPS310_BACKGROUND);
> + DPS310_PRS_EN | DPS310_TEMP_EN |
> + DPS310_BACKGROUND);
> if (r < 0)
> goto err;
>
> @@ -421,7 +696,7 @@ static int dps310_probe(struct i2c_client *client,
> if (r < 0)
> goto err;
>
> - r = dps310_get_temp_coef(data);
> + r = dps310_get_coefs(data);
> if (r < 0)
> goto err;
>
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> + * Calibration coefficients required for reporting temperature.
> + * They are available 40ms after the device has started
> + */
> + r = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
> + ready & DPS310_COEF_RDY, 1, 4);
> + if (r < 0)
> + goto err;
> +
> + r = dps310_get_temp_coef(data);
> + if (r < 0)
> + goto err;
> +
> + r = devm_iio_device_register(>dev, iio);
> + if (r)
> + goto err;
> +
> + i2c_set_clientdata(client, iio);
> +
> + dev_info(>dev, "%s: sensor '%s'\n", dev_name(>dev),
> + client->name);
don't clutter the log
> +
> + return 0;
> +
> +err:
> + regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC);
> + return r;
> +}
> +
> +static int dps310_remove(struct i2c_client *client)
> +{
> + struct dps310_data *data = i2c_get_clientdata(client);
> +
> + return regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC);
> +}
> +
> +static const struct i2c_device_id dps310_id[] = {
> + { "dps310", 0 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, dps310_id);
> +
> +static const unsigned short normal_i2c[] = {
> + 0x77, 0x76, I2C_CLIENT_END
> +};
> +
> +static struct i2c_driver dps310_driver = {
> + .driver = {
> + .name = "dps310",
> + },
> + .probe = dps310_probe,
> + .remove = dps310_remove,
> + .address_list = normal_i2c,
> + .id_table = dps310_id,
> +};
> +module_i2c_driver(dps310_driver);
> +
> +MODULE_AUTHOR("Joel Stanley ");
> +MODULE_DESCRIPTION("Infineon DPS310 pressure and temperature sensor");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
dev_err(>dev, "IIO device register failed");
> + iio_triggered_buffer_cleanup(indio_dev);
> + return ret;
> + }
> +
> + i2c_set_clientdata(client, indio_dev);
> +
> + dev_info(>dev, "%s: sensor '%s'\n",
> +
ixart,pat9125";
> + reg = <0x75>;
> + interrupt-parent = <>;
> + interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
> +};
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
config_sensor(als_dev, als_dev->events_enabled,
> +als_dev->cur_sensitivity);
> +
> + return 0;
> +}
> +#endif
> +
> +static struct hid_driver appleals_hid_driver = {
> + .name = "apple-ib-als",
> + .probe = appleals_probe,
> + .remove = appleals_remove,
> + .event = appleals_hid_event,
> +#ifdef CONFIG_PM
> + .reset_resume = appleals_reset_resume,
> +#endif
> +};
> +
> +static int appleals_platform_probe(struct platform_device *pdev)
> +{
> + struct appleib_platform_data *pdata = pdev->dev.platform_data;
> + struct appleib_device *ib_dev = pdata->ib_dev;
> + struct appleals_device *als_dev;
> + int rc;
> +
> + als_dev = kzalloc(sizeof(*als_dev), GFP_KERNEL);
> + if (!als_dev)
> + return -ENOMEM;
> +
> + als_dev->ib_dev = ib_dev;
> + als_dev->log_dev = pdata->log_dev;
> +
> + rc = appleib_register_hid_driver(ib_dev, _hid_driver, als_dev);
> + if (rc) {
> + dev_err(als_dev->log_dev, "Error registering hid driver: %d\n",
> + rc);
> + goto error;
> + }
> +
> + platform_set_drvdata(pdev, als_dev);
> +
> + return 0;
> +
> +error:
> + kfree(als_dev);
> + return rc;
> +}
> +
> +static int appleals_platform_remove(struct platform_device *pdev)
> +{
> + struct appleib_platform_data *pdata = pdev->dev.platform_data;
> + struct appleib_device *ib_dev = pdata->ib_dev;
> + struct appleals_device *als_dev = platform_get_drvdata(pdev);
> + int rc;
> +
> + rc = appleib_unregister_hid_driver(ib_dev, _hid_driver);
> + if (rc) {
> + dev_err(als_dev->log_dev,
> + "Error unregistering hid driver: %d\n", rc);
> + goto error;
> + }
> +
> + kfree(als_dev);
> +
> + return 0;
> +
> +error:
> + return rc;
> +}
> +
> +static const struct platform_device_id appleals_platform_ids[] = {
> + { .name = PLAT_NAME_IB_ALS },
> + { }
> +};
> +MODULE_DEVICE_TABLE(platform, appleals_platform_ids);
> +
> +static struct platform_driver appleals_platform_driver = {
> + .id_table = appleals_platform_ids,
> + .driver = {
> + .name = "apple-ib-als",
> + },
> + .probe = appleals_platform_probe,
> + .remove = appleals_platform_remove,
> +};
> +
> +module_platform_driver(appleals_platform_driver);
> +
> +MODULE_AUTHOR("Ronald Tschalär");
> +MODULE_DESCRIPTION("Apple iBridge ALS driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
me, indio_dev);
> + if (ret < 0) {
> + dev_err(dev, "request_irq: %d\n", ret);
> + return ret;
> + }
> + }
> +
> + ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
> + iio_pollfunc_store_time, mb12x2_trigger_handler, NULL);
> + if (ret < 0) {
> + dev_err(dev, "setup of iio triggered buffer failed\n");
> + return ret;
> + }
> +
> + return devm_iio_device_register(dev, indio_dev);
> +}
> +
> +static const struct of_device_id of_mb12x2_match[] = {
> + { .compatible = "maxbotix,i2cxl", },
> + {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, of_mb12x2_match);
> +
> +static const struct i2c_device_id mb12x2_id[] = {
> + { "maxbotix-i2cxl", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, mb12x2_id);
> +
> +static struct i2c_driver mb12x2_driver = {
> + .driver = {
> + .name = "maxbotix-i2cxl",
> + .of_match_table = of_mb12x2_match,
> + },
> + .probe = mb12x2_probe,
> + .id_table = mb12x2_id,
> +};
> +module_i2c_driver(mb12x2_driver);
> +
> +MODULE_AUTHOR("Andreas Klinger ");
> +MODULE_DESCRIPTION("Maxbotix I2CXL-MaxSonar i2c ultrasonic ranger driver");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
IRQF_TRIGGER_FALLING, id->name, indio_dev);
> + if (ret < 0) {
> + dev_err(dev, "request_irq: %d\n", ret);
> + return ret;
> + }
> + }
> +
> + ret = devm_iio_triggered_buffer_setup(dev, in
2.o
alphabetic order please
> obj-$(CONFIG_LIDAR_LITE_V2) += pulsedlight-lidar-lite-v2.o
> obj-$(CONFIG_RFD77402) += rfd77402.o
> obj-$(CONFIG_SRF04) += srf04.o
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
d)
> +{
> + struct ap3216c_data *data;
> + struct iio_dev *indio_dev;
> + int ret;
> +
> + indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + data = iio_priv(indio_dev);
> + data->client = client;
> + indio_dev->dev.parent = >dev;
> + indio_dev->info = _info;
> + indio_dev->name = AP3216C_DRV_NAME;
> + indio_dev->channels = ap3216c_channels;
> + indio_dev->num_channels = ARRAY_SIZE(ap3216c_channels);
> +
> + data->regmap = devm_regmap_init_i2c(client, _regmap_config);
> + if (IS_ERR(data->regmap)) {
> + dev_err(>dev, "Failed to allocate register map\n");
> + return PTR_ERR(data->regmap);
> + }
> +
> + /* Default to thresh events disabled */
> + data->als_thresh_en = false;
> + data->prox_thresh_en = false;
> +
> + /*
> + * Require that that the interrupt is cleared only when the INT
that that
> + * register is written to, instead of when data is read. This
> + * prevents the interrupt from falsely reporting IRQ_NONE.
> + */
> + ret = regmap_write(data->regmap,
> +AP3216C_INT_CLR, AP3216C_INT_CLR_MANUAL);
> + if (ret < 0)
> + return ret;
> +
> + /* Before setting up IRQ, clear any stale interrupt */
> + ret = ap3216c_clear_int(data);
> + if (ret < 0)
> + return ret;
> +
> + if (client->irq) {
> + ret = devm_request_threaded_irq(>dev, client->irq,
> + NULL, ap3216c_event_handler,
> + IRQF_TRIGGER_FALLING |
> + IRQF_SHARED | IRQF_ONESHOT,
> + client->name, indio_dev);
> + if (ret)
> + return ret;
> + }
> +
> + /* Enable ALS and PS+IR */
> + ret = regmap_write(data->regmap, AP3216C_SYS, AP3216C_SYS_MODE_ALS_PS);
> + if (ret < 0)
> + return ret;
> +
> + return devm_iio_device_register(>dev, indio_dev);
> +}
> +
> +static const struct of_device_id ap3216c_of_match[] = {
> + { .compatible = "liteon,ap3216c", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, ap3216c_of_match);
> +
> +static const struct i2c_device_id ap3216c_id[] = {
> + {"ap3216c", 0},
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, ap3216c_id);
> +
> +static struct i2c_driver ap3216c_driver = {
> + .driver = {
> + .name = AP3216C_DRV_NAME,
> + },
> + .probe = ap3216c_probe,
> + .id_table = ap3216c_id,
> +};
> +module_i2c_driver(ap3216c_driver);
> +
> +MODULE_AUTHOR("Robert Eshleman ");
> +MODULE_DESCRIPTION("APC3216C Ambient Light and Proximity Sensor");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
goto error_disable_reg;
> + }
> +
> + st->filter_gpio = devm_gpiod_get_optional(>dev,
> + "filter",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(st->filter_gpio)) {
> + ret = PTR_ERR(st->filter_gpio);
> + dev_err(>dev,
> + "Failed to request filter GPIO: %d\n",
> + ret);
> + goto error_disable_reg;
> + }
> + }
> +
> ret = ad_sd_setup_buffer_and_trigger(indio_dev);
> if (ret)
> goto error_disable_reg;
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
ret = pms7003_do_cmd(state, CMD_WAKEUP);
> + if (ret) {
> + dev_err(>dev, "failed to wakeup sensor\n");
> + return ret;
> + }
> +
> + ret = pms7003_do_cmd(state, CMD_ENTER_PASSIVE_MODE);
> + if (ret) {
> + dev_err(>dev, "failed to enter passive mode\n");
> + return ret;
> + }
> +
> + ret = devm_add_action_or_reset(>dev, pms7003_stop, state);
> + if (ret)
> + return ret;
> +
> + ret = devm_iio_triggered_buffer_setup(>dev, indio_dev, NULL,
> + pms7003_trigger_handler, NULL);
> + if (ret)
> + return ret;
> +
> + return devm_iio_device_register(>dev, indio_dev);
> +}
> +
> +static const struct of_device_id pms7003_of_match[] = {
> + { .compatible = "plantower,pms7003" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, pms7003_of_match);
> +
> +static struct serdev_device_driver pms7003_driver = {
> + .driver = {
> + .name = PMS7003_DRIVER_NAME,
> + .of_match_table = pms7003_of_match,
> + },
> + .probe = pms7003_probe,
> +};
> +module_serdev_device_driver(pms7003_driver);
> +
> +MODULE_AUTHOR("Tomasz Duszynski ");
> +MODULE_DESCRIPTION("Plantower PMS7003 particulate matter sensor driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
llfunc_store_time.
>
> There 'might' be a reason to do it differently depending
> on whether you really need it to be that good if you
> can't identify whether it is your interrupt until the
> interrupt thread.
>
>
> > + return IRQ_WAKE_THREAD;
> > +}
> > +
> > +static int max44009_probe(struct i2c_client *client,
> > + const struct i2c_device_id *id)
> > +{
> > + struct max44009_data *data;
> > + struct iio_dev *indio_dev;
> > + int ret;
> > +
> > + indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
> > + if (!indio_dev) {
> > + return -ENOMEM;
> > + }
> > + data = iio_priv(indio_dev);
> > + i2c_set_clientdata(client, indio_dev);
> > + data->client = client;
> > + indio_dev->dev.parent = >dev;
> > + indio_dev->info = _info;
> > + indio_dev->modes = INDIO_DIRECT_MODE;
> > + indio_dev->name = MAX44009_DRV_NAME;
> > + indio_dev->channels = max44009_channels;
> > + indio_dev->num_channels = ARRAY_SIZE(max44009_channels);
> > + mutex_init(>lock);
> > +
> > + /* Clear stale interrupt bit */
> > + ret = max44009_read_reg(data, MAX44009_REG_STATUS);
> > + if (ret < 0) {
> > + goto err;
> > + }
> > +
> > + if (client->irq > 0) {
> > + ret = devm_request_threaded_irq(>dev, client->irq,
> > + max44009_irq_handler,
>
> This is wrong. The interrupt handler should call the iio_trigger_poll
> functions
> to cause the trigger handlers for all attached devices to be called.
>
> If for some reason the trigger is only suitable for use by this device
> then things get more blurred, but if not, the interrupt handler itself
> should establish that the interrupt is the data ready signal and call
> iio_trigger_poll. If it is in a thread, call iio_trigger_poll_chained.
>
> The interrupt should be cleared (if it hasn't naturally happened for
> some other reason, in the trigger try_reenable callback.
>
>
> > + max44009_trigger_handler,
> > + IRQF_TRIGGER_FALLING |
> > + IRQF_ONESHOT,
> > + MAX44009_IRQ_NAME, indio_dev);
> > + if (ret < 0) {
> > + goto err;
> > + }
> > +
> > + ret = devm_iio_triggered_buffer_setup(>dev, indio_dev,
> > + max44009_irq_handler,
> > + max44009_trigger_handler,
> > + NULL);
> > + if (ret < 0) {
>
> It's going to change anyway (see below) but note kernel style is no
> brackets when only one item in an block like this.
>
> > + goto err;
> > + }
> > +
> > + data->trigger = devm_iio_trigger_alloc(indio_dev->dev.parent,
> > + "%s-dev%d",
> > + indio_dev->name,
> > + indio_dev->id);
> > + if (!data->trigger) {
> > + ret = -ENOMEM;
> > + goto err;
> > + }
> > + data->trigger->dev.parent = indio_dev->dev.parent;
> > + data->trigger->ops = _trigger_ops;
> > + iio_trigger_set_drvdata(data->trigger, indio_dev);
> > +
> > + ret = devm_iio_trigger_register(>dev, data->trigger);
> > + if (ret < 0) {
> > + goto err;
> > + }
> > + }
> > +
> > + ret = devm_iio_device_register(>dev, indio_dev);
> > + if (ret < 0) {
> > + goto err;
>
> Without the mutex destroy these all just become return ret;
>
> > + }
> > +
> > + return 0;
> > +err:
> > + mutex_destroy(>lock);
>
> mutex destroy is only really useful for lock debugging. Given we don't
> leave anything behind here anyway, it just makes the flow more complex
> for no gain. We very rarely bother with it as a result.
>
> > + return ret;
> > +}
> > +
> > +static const struct i2c_device_id max44009_id[] = {
> > + { "max44009", 0 },
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(i2c, max44009_id);
> > +
> > +static struct i2c_driver max44009_driver = {
> > + .driver = {
> > + .name = MAX44009_DRV_NAME,
> > + },
> > + .probe = max44009_probe,
> > + .id_table = max44009_id,
> > +};
> > +module_i2c_driver(max44009_driver);
> > +
> > +static const struct of_device_id max44009_of_match[] = {
> > + { .compatible = "maxim,max44009" },
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(of, max44009_of_match);
> > +
> > +MODULE_AUTHOR("Robert Eshleman ");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_VERSION("1.0.0");
> Please drop. MODULE_VERSION provides very little useful info
> and tends to lead to people assuming it does.
>
> Userspace has no obligation to ever look at it and we can't
> break userspace that doesn't so it doesn't provide any value.
>
> > +MODULE_DESCRIPTION("MAX44009 ambient light sensor driver");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
..5e30bc0f5149
> --- /dev/null
> +++ b/drivers/iio/magnetometer/rm3100.h
> @@ -0,0 +1,90 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Header file for PNI RM3100 driver
> + *
> + * Copyright (C) 2018 Song Qiang
> + */
> +
> +#ifndef RM3100_CORE_H
> +#define RM3100_CORE_H
> +
> +#include
> +#include
> +
> +#define RM_REG_REV_ID0x36
> +
> +/* Cycle Count Registers MSBs and LSBs. */
> +#define RM_REG_CCXM 0x04
> +#define RM_REG_CCXL 0x05
> +#define RM_REG_CCYM 0x06
> +#define RM_REG_CCYL 0x07
> +#define RM_REG_CCZM 0x08
> +#define RM_REG_CCZL 0x09
> +
> +/* Single Measurement Mode register. */
> +#define RM_REG_POLL 0x00
> +#define RM_POLL_PMX BIT(4)
> +#define RM_POLL_PMY BIT(5)
> +#define RM_POLL_PMZ BIT(6)
> +
> +/* Continues Measurement Mode register. */
> +#define RM_REG_CMM 0x01
> +#define RM_CMM_START BIT(0)
> +#define RM_CMM_DRDM BIT(2)
> +#define RM_CMM_PMX BIT(4)
> +#define RM_CMM_PMY BIT(5)
> +#define RM_CMM_PMZ BIT(6)
> +
> +/* TiMe Rate Configuration register. */
> +#define RM_REG_TMRC 0x0B
> +#define RM_TMRC_OFFSET 0x92
> +
> +/* Result Status register. */
> +#define RM_REG_STATUS0x34
> +#define RM_STATUS_DRDY BIT(7)
> +
> +/* Measurement result registers. */
> +#define RM_REG_MX2 0x24
> +#define RM_REG_MX1 0x25
> +#define RM_REG_MX0 0x26
> +#define RM_REG_MY2 0x27
> +#define RM_REG_MY1 0x28
> +#define RM_REG_MY0 0x29
> +#define RM_REG_MZ2 0x2a
> +#define RM_REG_MZ1 0x2b
> +#define RM_REG_MZ0 0x2c
> +
> +#define RM_REG_HSHAKE0x35
> +
> +#define RM_W_REG_START RM_REG_POLL
> +#define RM_W_REG_END RM_REG_REV_ID
> +#define RM_R_REG_START RM_REG_POLL
> +#define RM_R_REG_END RM_REG_HSHAKE
> +#define RM_V_REG_START RM_REG_MX2
> +#define RM_V_REG_END RM_REG_HSHAKE
> +
> +/* Built-In Self Test reigister. */
> +#define RM_REG_BIST 0x33
> +
> +struct rm3100_data {
> + struct device *dev;
> + struct regmap *regmap;
> + struct completion measuring_done;
> + bool use_interrupt;
> +
> + int conversion_time;
> +
> + /* To protect consistency of every measurement and sampling
> + * frequency change operations.
> + */
> + struct mutex lock;
> +};
> +
> +extern const struct regmap_access_table rm3100_readable_table;
> +extern const struct regmap_access_table rm3100_writable_table;
> +extern const struct regmap_access_table rm3100_volatile_table;
> +
> +int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq);
> +int rm3100_common_remove(struct device *dev);
> +
> +#endif /* RM3100_CORE_H */
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
..5e30bc0f5149
> --- /dev/null
> +++ b/drivers/iio/magnetometer/rm3100.h
> @@ -0,0 +1,90 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Header file for PNI RM3100 driver
> + *
> + * Copyright (C) 2018 Song Qiang
> + */
> +
> +#ifndef RM3100_CORE_H
> +#define RM3100_CORE_H
> +
> +#include
> +#include
> +
> +#define RM_REG_REV_ID0x36
> +
> +/* Cycle Count Registers MSBs and LSBs. */
> +#define RM_REG_CCXM 0x04
> +#define RM_REG_CCXL 0x05
> +#define RM_REG_CCYM 0x06
> +#define RM_REG_CCYL 0x07
> +#define RM_REG_CCZM 0x08
> +#define RM_REG_CCZL 0x09
> +
> +/* Single Measurement Mode register. */
> +#define RM_REG_POLL 0x00
> +#define RM_POLL_PMX BIT(4)
> +#define RM_POLL_PMY BIT(5)
> +#define RM_POLL_PMZ BIT(6)
> +
> +/* Continues Measurement Mode register. */
> +#define RM_REG_CMM 0x01
> +#define RM_CMM_START BIT(0)
> +#define RM_CMM_DRDM BIT(2)
> +#define RM_CMM_PMX BIT(4)
> +#define RM_CMM_PMY BIT(5)
> +#define RM_CMM_PMZ BIT(6)
> +
> +/* TiMe Rate Configuration register. */
> +#define RM_REG_TMRC 0x0B
> +#define RM_TMRC_OFFSET 0x92
> +
> +/* Result Status register. */
> +#define RM_REG_STATUS0x34
> +#define RM_STATUS_DRDY BIT(7)
> +
> +/* Measurement result registers. */
> +#define RM_REG_MX2 0x24
> +#define RM_REG_MX1 0x25
> +#define RM_REG_MX0 0x26
> +#define RM_REG_MY2 0x27
> +#define RM_REG_MY1 0x28
> +#define RM_REG_MY0 0x29
> +#define RM_REG_MZ2 0x2a
> +#define RM_REG_MZ1 0x2b
> +#define RM_REG_MZ0 0x2c
> +
> +#define RM_REG_HSHAKE0x35
> +
> +#define RM_W_REG_START RM_REG_POLL
> +#define RM_W_REG_END RM_REG_REV_ID
> +#define RM_R_REG_START RM_REG_POLL
> +#define RM_R_REG_END RM_REG_HSHAKE
> +#define RM_V_REG_START RM_REG_MX2
> +#define RM_V_REG_END RM_REG_HSHAKE
> +
> +/* Built-In Self Test reigister. */
> +#define RM_REG_BIST 0x33
> +
> +struct rm3100_data {
> + struct device *dev;
> + struct regmap *regmap;
> + struct completion measuring_done;
> + bool use_interrupt;
> +
> + int conversion_time;
> +
> + /* To protect consistency of every measurement and sampling
> + * frequency change operations.
> + */
> + struct mutex lock;
> +};
> +
> +extern const struct regmap_access_table rm3100_readable_table;
> +extern const struct regmap_access_table rm3100_writable_table;
> +extern const struct regmap_access_table rm3100_volatile_table;
> +
> +int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq);
> +int rm3100_common_remove(struct device *dev);
> +
> +#endif /* RM3100_CORE_H */
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
IGHT_UV] = "uv",
> > > + [IIO_MOD_LIGHT_WHITE] = "white",
> > > [IIO_MOD_QUATERNION] = "quaternion",
> > > [IIO_MOD_TEMP_AMBIENT] = "ambient",
> > > [IIO_MOD_TEMP_OBJECT] = "object",
> > > @@ -178,6 +179,7 @@ static bool event_is_known(struct iio_event_data
> > > *event)
> > > case IIO_MOD_LIGHT_GREEN:
> > > case IIO_MOD_LIGHT_BLUE:
> > > case IIO_MOD_LIGHT_UV:
> > > + case IIO_MOD_LIGHT_WHITE:
> > > case IIO_MOD_QUATERNION:
> > > case IIO_MOD_TEMP_AMBIENT:
> > > case IIO_MOD_TEMP_OBJECT:
> > >
> >
>
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
IGHT_UV] = "uv",
> > > + [IIO_MOD_LIGHT_WHITE] = "white",
> > > [IIO_MOD_QUATERNION] = "quaternion",
> > > [IIO_MOD_TEMP_AMBIENT] = "ambient",
> > > [IIO_MOD_TEMP_OBJECT] = "object",
> > > @@ -178,6 +179,7 @@ static bool event_is_known(struct iio_event_data
> > > *event)
> > > case IIO_MOD_LIGHT_GREEN:
> > > case IIO_MOD_LIGHT_BLUE:
> > > case IIO_MOD_LIGHT_UV:
> > > + case IIO_MOD_LIGHT_WHITE:
> > > case IIO_MOD_QUATERNION:
> > > case IIO_MOD_TEMP_AMBIENT:
> > > case IIO_MOD_TEMP_OBJECT:
> > >
> >
>
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> +}
> +
> +static int vcnl4035_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> +
> + iio_triggered_buffer_cleanup(indio_dev);
> + iio_trigger_unregister(data->drdy_trigger0);
> + iio_device_unregister(indio_dev);
> +
> + pm_runtime_disable(>dev);
> + pm_runtime_set_suspended(>dev);
> + pm_runtime_put_noidle(>dev);
> +
> + return vcnl4035_set_als_power_state(iio_priv(indio_dev),
> + VCNL4035_MODE_ALS_DISABLE);
> +}
> +
> +#ifdef CONFIG_PM
> +static int vcnl4035_runtime_suspend(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
> + regcache_mark_dirty(data->regmap);
> +
> + return ret;
> +}
> +
> +static int vcnl4035_runtime_resume(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + regcache_sync(data->regmap);
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE);
> + if (ret < 0)
> + return ret;
> + /* wait for 1 ALS integration cycle */
> + msleep(data->als_it_val * 100);
> +
> + return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops vcnl4035_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> + pm_runtime_force_resume)
> + SET_RUNTIME_PM_OPS(vcnl4035_runtime_suspend,
> +vcnl4035_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id vcnl4035_of_match[] = {
> + { .compatible = "vishay,vcnl4035", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, vcnl4035_of_match);
> +
> +static const struct i2c_device_id vcnl4035_id[] = {
> + { "vcnl4035", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, vcnl4035_id);
> +
> +static struct i2c_driver vcnl4035_driver = {
> + .driver = {
> + .name = VCNL4035_DRV_NAME,
> + .pm = _pm_ops,
> + .of_match_table = of_match_ptr(vcnl4035_of_match),
> + },
> + .probe = vcnl4035_probe,
> + .remove = vcnl4035_remove,
> + .id_table = vcnl4035_id,
> +};
> +
> +module_i2c_driver(vcnl4035_driver);
> +
> +MODULE_AUTHOR("Parthiban Nallathambi ");
> +MODULE_DESCRIPTION("VCNL4035 Ambient Light Sensor driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> +}
> +
> +static int vcnl4035_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> +
> + iio_triggered_buffer_cleanup(indio_dev);
> + iio_trigger_unregister(data->drdy_trigger0);
> + iio_device_unregister(indio_dev);
> +
> + pm_runtime_disable(>dev);
> + pm_runtime_set_suspended(>dev);
> + pm_runtime_put_noidle(>dev);
> +
> + return vcnl4035_set_als_power_state(iio_priv(indio_dev),
> + VCNL4035_MODE_ALS_DISABLE);
> +}
> +
> +#ifdef CONFIG_PM
> +static int vcnl4035_runtime_suspend(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
> + regcache_mark_dirty(data->regmap);
> +
> + return ret;
> +}
> +
> +static int vcnl4035_runtime_resume(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + regcache_sync(data->regmap);
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE);
> + if (ret < 0)
> + return ret;
> + /* wait for 1 ALS integration cycle */
> + msleep(data->als_it_val * 100);
> +
> + return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops vcnl4035_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> + pm_runtime_force_resume)
> + SET_RUNTIME_PM_OPS(vcnl4035_runtime_suspend,
> +vcnl4035_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id vcnl4035_of_match[] = {
> + { .compatible = "vishay,vcnl4035", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, vcnl4035_of_match);
> +
> +static const struct i2c_device_id vcnl4035_id[] = {
> + { "vcnl4035", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, vcnl4035_id);
> +
> +static struct i2c_driver vcnl4035_driver = {
> + .driver = {
> + .name = VCNL4035_DRV_NAME,
> + .pm = _pm_ops,
> + .of_match_table = of_match_ptr(vcnl4035_of_match),
> + },
> + .probe = vcnl4035_probe,
> + .remove = vcnl4035_remove,
> + .id_table = vcnl4035_id,
> +};
> +
> +module_i2c_driver(vcnl4035_driver);
> +
> +MODULE_AUTHOR("Parthiban Nallathambi ");
> +MODULE_DESCRIPTION("VCNL4035 Ambient Light Sensor driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
[IIO_MOD_QUATERNION] = "quaternion",
> [IIO_MOD_TEMP_AMBIENT] = "ambient",
> [IIO_MOD_TEMP_OBJECT] = "object",
> @@ -178,6 +179,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_MOD_LIGHT_GREEN:
> case IIO_MOD_LIGHT_BLUE:
> case IIO_MOD_LIGHT_UV:
> + case IIO_MOD_LIGHT_WHITE:
> case IIO_MOD_QUATERNION:
> case IIO_MOD_TEMP_AMBIENT:
> case IIO_MOD_TEMP_OBJECT:
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
[IIO_MOD_QUATERNION] = "quaternion",
> [IIO_MOD_TEMP_AMBIENT] = "ambient",
> [IIO_MOD_TEMP_OBJECT] = "object",
> @@ -178,6 +179,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_MOD_LIGHT_GREEN:
> case IIO_MOD_LIGHT_BLUE:
> case IIO_MOD_LIGHT_UV:
> + case IIO_MOD_LIGHT_WHITE:
> case IIO_MOD_QUATERNION:
> case IIO_MOD_TEMP_AMBIENT:
> case IIO_MOD_TEMP_OBJECT:
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> + ret = devm_iio_triggered_buffer_setup(>spi->dev,
> + indio_dev, NULL,
> + adxl372_trigger_handler,
> + _buffer_ops);
> + if (ret < 0)
> + return ret;
> +
> + iio_buffer_set_attrs(indio_dev->buffer, adxl372_fifo_attributes);
> +
> + if (st->spi->irq) {
> + st->dready_trig = devm_iio_trigger_alloc(>spi->dev,
> + "%s-dev%d",
> + indio_dev->name,
> + indio_dev->id);
> + if (st->dready_trig == NULL)
> + return -ENOMEM;
> +
> + st->dready_trig->ops = _trigger_ops;
> + st->dready_trig->dev.parent = >spi->dev;
> + iio_trigger_set_drvdata(st->dready_trig, indio_dev);
> + ret = devm_iio_trigger_register(>spi->dev, st->dready_trig);
> + if (ret < 0)
> + return ret;
> +
> + indio_dev->trig = iio_trigger_get(st->dready_trig);
> +
> + ret = devm_request_threaded_irq(>spi->dev, st->spi->irq,
> + iio_trigger_generic_data_rdy_poll,
> + NULL,
> + IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> + indio_dev->name, st->dready_trig);
> + if (ret < 0)
> + return ret;
> + }
> +
> return devm_iio_device_register(>spi->dev, indio_dev);
> }
>
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> + ret = devm_iio_triggered_buffer_setup(>spi->dev,
> + indio_dev, NULL,
> + adxl372_trigger_handler,
> + _buffer_ops);
> + if (ret < 0)
> + return ret;
> +
> + iio_buffer_set_attrs(indio_dev->buffer, adxl372_fifo_attributes);
> +
> + if (st->spi->irq) {
> + st->dready_trig = devm_iio_trigger_alloc(>spi->dev,
> + "%s-dev%d",
> + indio_dev->name,
> + indio_dev->id);
> + if (st->dready_trig == NULL)
> + return -ENOMEM;
> +
> + st->dready_trig->ops = _trigger_ops;
> + st->dready_trig->dev.parent = >spi->dev;
> + iio_trigger_set_drvdata(st->dready_trig, indio_dev);
> + ret = devm_iio_trigger_register(>spi->dev, st->dready_trig);
> + if (ret < 0)
> + return ret;
> +
> + indio_dev->trig = iio_trigger_get(st->dready_trig);
> +
> + ret = devm_request_threaded_irq(>spi->dev, st->spi->irq,
> + iio_trigger_generic_data_rdy_poll,
> + NULL,
> + IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> + indio_dev->name, st->dready_trig);
> + if (ret < 0)
> + return ret;
> + }
> +
> return devm_iio_device_register(>spi->dev, indio_dev);
> }
>
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
)
> + return ret;
> + }
> +
> + /* Store gain values to better calculate scale values */
> + mcp3911_get_hwgain(adc, 0, >gain[0]);
> + mcp3911_get_hwgain(adc, 1, >gain[1]);
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->dev.of_node = spi->dev.of_node;
> + indio_dev->name = spi_get_device_id(spi)->name;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> + spi_set_drvdata(spi, indio_dev);
> +
> + indio_dev->channels = mcp3911_channels;
> + indio_dev->num_channels = ARRAY_SIZE(mcp3911_channels);
> +
> + mutex_init(>lock);
> +
> + ret = iio_device_register(indio_dev);
> + if (ret)
> + goto reg_disable;
> +
> + return ret;
> +
> +reg_disable:
> + if (adc->vref)
> + regulator_disable(adc->vref);
> +
> + return ret;
> +}
> +
> +static int mcp3911_remove(struct spi_device *spi)
> +{
> + struct iio_dev *indio_dev = spi_get_drvdata(spi);
> + struct mcp3911 *adc = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> +
> + if (adc->vref)
> + regulator_disable(adc->vref);
> +
> + return 0;
> +}
> +
> +#if defined(CONFIG_OF)
> +static const struct of_device_id mcp3911_dt_ids[] = {
> + { .compatible = "microchip,mcp3911" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, mcp3911_dt_ids);
> +#endif
> +
> +static const struct spi_device_id mcp3911_id[] = {
> + { "mcp3911", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(spi, mcp3911_id);
> +
> +static struct spi_driver mcp3911_driver = {
> + .driver = {
> + .name = "mcp3911",
> + .of_match_table = of_match_ptr(mcp3911_dt_ids),
> + },
> + .probe = mcp3911_probe,
> + .remove = mcp3911_remove,
> + .id_table = mcp3911_id,
> +};
> +module_spi_driver(mcp3911_driver);
> +
> +MODULE_AUTHOR("Marcus Folkesson ");
> +MODULE_AUTHOR("Kent Gustavsson ");
> +MODULE_DESCRIPTION("Microchip Technology MCP3911");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
)
> + return ret;
> + }
> +
> + /* Store gain values to better calculate scale values */
> + mcp3911_get_hwgain(adc, 0, >gain[0]);
> + mcp3911_get_hwgain(adc, 1, >gain[1]);
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->dev.of_node = spi->dev.of_node;
> + indio_dev->name = spi_get_device_id(spi)->name;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> + spi_set_drvdata(spi, indio_dev);
> +
> + indio_dev->channels = mcp3911_channels;
> + indio_dev->num_channels = ARRAY_SIZE(mcp3911_channels);
> +
> + mutex_init(>lock);
> +
> + ret = iio_device_register(indio_dev);
> + if (ret)
> + goto reg_disable;
> +
> + return ret;
> +
> +reg_disable:
> + if (adc->vref)
> + regulator_disable(adc->vref);
> +
> + return ret;
> +}
> +
> +static int mcp3911_remove(struct spi_device *spi)
> +{
> + struct iio_dev *indio_dev = spi_get_drvdata(spi);
> + struct mcp3911 *adc = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> +
> + if (adc->vref)
> + regulator_disable(adc->vref);
> +
> + return 0;
> +}
> +
> +#if defined(CONFIG_OF)
> +static const struct of_device_id mcp3911_dt_ids[] = {
> + { .compatible = "microchip,mcp3911" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, mcp3911_dt_ids);
> +#endif
> +
> +static const struct spi_device_id mcp3911_id[] = {
> + { "mcp3911", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(spi, mcp3911_id);
> +
> +static struct spi_driver mcp3911_driver = {
> + .driver = {
> + .name = "mcp3911",
> + .of_match_table = of_match_ptr(mcp3911_dt_ids),
> + },
> + .probe = mcp3911_probe,
> + .remove = mcp3911_remove,
> + .id_table = mcp3911_id,
> +};
> +module_spi_driver(mcp3911_driver);
> +
> +MODULE_AUTHOR("Marcus Folkesson ");
> +MODULE_AUTHOR("Kent Gustavsson ");
> +MODULE_DESCRIPTION("Microchip Technology MCP3911");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
off:
> + return vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
I think we want to return the 'ret' value indicating the original failure,
not the return value of vcnl4035_set_als_power_state() which is likely success
> +}
> +
> +static int vcnl4035_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> +
> + pm_runtime_disable(>dev);
> + pm_runtime_set_suspended(>dev);
> + pm_runtime_put_noidle(>dev);
> +
> + return vcnl4035_set_als_power_state(iio_priv(indio_dev),
> + VCNL4035_MODE_ALS_DISABLE);
> +}
> +
> +#ifdef CONFIG_PM
> +static int vcnl4035_runtime_suspend(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + mutex_lock(>lock);
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
> + regcache_mark_dirty(data->regmap);
> + mutex_unlock(>lock);
> +
> + return ret;
> +}
> +
> +static int vcnl4035_runtime_resume(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + regcache_sync(data->regmap);
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE);
> + if (ret < 0)
> + return ret;
> + /* wait for 1 ALS integration cycle */
> + msleep(data->als_it_val * 100);
> +
> + return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops vcnl4035_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> + pm_runtime_force_resume)
> + SET_RUNTIME_PM_OPS(vcnl4035_runtime_suspend,
> +vcnl4035_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id vcnl4035_of_match[] = {
> + { .compatible = "vishay,vcnl4035", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, vcnl4035_of_match);
> +
> +static const struct i2c_device_id vcnl4035_id[] = {
> + { "vcnl4035", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, vcnl4035_id);
> +
> +static struct i2c_driver vcnl4035_driver = {
> + .driver = {
> + .name = VCNL4035_DRV_NAME,
> + .pm = _pm_ops,
> + .of_match_table = of_match_ptr(vcnl4035_of_match),
> + },
> + .probe = vcnl4035_probe,
> + .remove = vcnl4035_remove,
> + .id_table = vcnl4035_id,
> +};
> +
> +module_i2c_driver(vcnl4035_driver);
> +
> +MODULE_AUTHOR("Parthiban Nallathambi ");
> +MODULE_DESCRIPTION("VCNL4035 Ambient Light Sensor driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
off:
> + return vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
I think we want to return the 'ret' value indicating the original failure,
not the return value of vcnl4035_set_als_power_state() which is likely success
> +}
> +
> +static int vcnl4035_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> +
> + pm_runtime_disable(>dev);
> + pm_runtime_set_suspended(>dev);
> + pm_runtime_put_noidle(>dev);
> +
> + return vcnl4035_set_als_power_state(iio_priv(indio_dev),
> + VCNL4035_MODE_ALS_DISABLE);
> +}
> +
> +#ifdef CONFIG_PM
> +static int vcnl4035_runtime_suspend(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + mutex_lock(>lock);
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE);
> + regcache_mark_dirty(data->regmap);
> + mutex_unlock(>lock);
> +
> + return ret;
> +}
> +
> +static int vcnl4035_runtime_resume(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct vcnl4035_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + regcache_sync(data->regmap);
> + ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE);
> + if (ret < 0)
> + return ret;
> + /* wait for 1 ALS integration cycle */
> + msleep(data->als_it_val * 100);
> +
> + return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops vcnl4035_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> + pm_runtime_force_resume)
> + SET_RUNTIME_PM_OPS(vcnl4035_runtime_suspend,
> +vcnl4035_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id vcnl4035_of_match[] = {
> + { .compatible = "vishay,vcnl4035", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, vcnl4035_of_match);
> +
> +static const struct i2c_device_id vcnl4035_id[] = {
> + { "vcnl4035", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, vcnl4035_id);
> +
> +static struct i2c_driver vcnl4035_driver = {
> + .driver = {
> + .name = VCNL4035_DRV_NAME,
> + .pm = _pm_ops,
> + .of_match_table = of_match_ptr(vcnl4035_of_match),
> + },
> + .probe = vcnl4035_probe,
> + .remove = vcnl4035_remove,
> + .id_table = vcnl4035_id,
> +};
> +
> +module_i2c_driver(vcnl4035_driver);
> +
> +MODULE_AUTHOR("Parthiban Nallathambi ");
> +MODULE_DESCRIPTION("VCNL4035 Ambient Light Sensor driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
t_volt_ratio = data;
> + sc27xx_data->dev = >dev;
> +
> + ret = sc27xx_adc_enable(sc27xx_data);
> + if (ret) {
> + dev_err(>dev, "failed to enable ADC module\n");
> + goto free_hwlock;
> + }
> +
> + ret = devm_request_threaded_irq(>dev, sc27xx_data->irq, NULL,
> + sc27xx_adc_isr, IRQF_ONESHOT,
> + pdev->name, sc27xx_data);
> + if (ret) {
> + dev_err(>dev, "failed to request ADC irq\n");
> + goto disable_adc;
> + }
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->name = dev_name(>dev);
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> + indio_dev->channels = sc27xx_channels;
> + indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels);
> + ret = devm_iio_device_register(>dev, indio_dev);
> + if (ret) {
> + dev_err(>dev, "could not register iio (ADC)");
> + goto disable_adc;
> + }
> +
> + platform_set_drvdata(pdev, indio_dev);
> + return 0;
> +
> +disable_adc:
> + sc27xx_adc_disable(sc27xx_data);
> +free_hwlock:
> + hwspin_lock_free(sc27xx_data->hwlock);
> + return ret;
> +}
> +
> +static int sc27xx_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct sc27xx_adc_data *sc27xx_data = iio_priv(indio_dev);
> +
> + sc27xx_adc_disable(sc27xx_data);
> + hwspin_lock_free(sc27xx_data->hwlock);
> + return 0;
> +}
> +
> +static const struct of_device_id sc27xx_adc_of_match[] = {
> + {
> + .compatible = "sprd,sc2731-adc",
> + .data = (void *)_adc_2731_ratio,
> + },
> + { }
> +};
> +
> +static struct platform_driver sc27xx_adc_driver = {
> + .probe = sc27xx_adc_probe,
> + .remove = sc27xx_adc_remove,
> + .driver = {
> + .name = "sc27xx-adc",
> + .of_match_table = sc27xx_adc_of_match,
> + },
> +};
> +
> +module_platform_driver(sc27xx_adc_driver);
> +
> +MODULE_AUTHOR("Freeman Liu ");
> +MODULE_DESCRIPTION("Spreadtrum SC27XX ADC Driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
t_volt_ratio = data;
> + sc27xx_data->dev = >dev;
> +
> + ret = sc27xx_adc_enable(sc27xx_data);
> + if (ret) {
> + dev_err(>dev, "failed to enable ADC module\n");
> + goto free_hwlock;
> + }
> +
> + ret = devm_request_threaded_irq(>dev, sc27xx_data->irq, NULL,
> + sc27xx_adc_isr, IRQF_ONESHOT,
> + pdev->name, sc27xx_data);
> + if (ret) {
> + dev_err(>dev, "failed to request ADC irq\n");
> + goto disable_adc;
> + }
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->name = dev_name(>dev);
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> + indio_dev->channels = sc27xx_channels;
> + indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels);
> + ret = devm_iio_device_register(>dev, indio_dev);
> + if (ret) {
> + dev_err(>dev, "could not register iio (ADC)");
> + goto disable_adc;
> + }
> +
> + platform_set_drvdata(pdev, indio_dev);
> + return 0;
> +
> +disable_adc:
> + sc27xx_adc_disable(sc27xx_data);
> +free_hwlock:
> + hwspin_lock_free(sc27xx_data->hwlock);
> + return ret;
> +}
> +
> +static int sc27xx_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct sc27xx_adc_data *sc27xx_data = iio_priv(indio_dev);
> +
> + sc27xx_adc_disable(sc27xx_data);
> + hwspin_lock_free(sc27xx_data->hwlock);
> + return 0;
> +}
> +
> +static const struct of_device_id sc27xx_adc_of_match[] = {
> + {
> + .compatible = "sprd,sc2731-adc",
> + .data = (void *)_adc_2731_ratio,
> + },
> + { }
> +};
> +
> +static struct platform_driver sc27xx_adc_driver = {
> + .probe = sc27xx_adc_probe,
> + .remove = sc27xx_adc_remove,
> + .driver = {
> + .name = "sc27xx-adc",
> + .of_match_table = sc27xx_adc_of_match,
> + },
> +};
> +
> +module_platform_driver(sc27xx_adc_driver);
> +
> +MODULE_AUTHOR("Freeman Liu ");
> +MODULE_DESCRIPTION("Spreadtrum SC27XX ADC Driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
if (ret < 0)
> + return ret;
> +
> + regval = ad5758_spi_reg_read(st, AD5758_DIGITAL_DIAG_RESULTS);
> + if (regval < 0)
> + return regval;
> +
> + /* Clear all the error flags */
> + ret = ad5758_spi_reg_write(st, AD5758_DIGITAL_DIAG_RESULTS, regval);
> + if (ret < 0)
> + return ret;
> +
> + /* Set the dc-to-dc current limit */
> + ret = ad5758_set_dc_dc_ilim(st, st->dc_dc_ilim);
> + if (ret < 0)
> + return ret;
> +
> + /* Configure the dc-to-dc controller mode */
> + ret = ad5758_set_dc_dc_conv_mode(st, st->dc_dc_mode);
> + if (ret < 0)
> + return ret;
> +
> + /* Configure the output range */
> + ret = ad5758_set_out_range(st, st->out_range);
> + if (ret < 0)
> + return ret;
> +
> + /* Enable Slew Rate Control, set the slew rate clock and step */
> + ret = ad5758_slew_rate_config(st, st->sr_config[0],
> + st->sr_config[1], st->sr_config[2]);
> + if (ret < 0)
> + return ret;
> +
> + /* Enable the VIOUT fault protection switch (FPS is closed) */
> + ret = ad5758_fault_prot_switch_en(st, 1);
> + if (ret < 0)
> + return ret;
> +
> + /* Power up the DAC and internal (INT) amplifiers */
> + ret = ad5758_internal_buffers_en(st, 1);
> + if (ret < 0)
> + return ret;
> +
> + /* Enable VIOUT */
> + ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
> + AD5758_DAC_CONFIG_OUT_EN_MSK,
> + AD5758_DAC_CONFIG_OUT_EN_MODE(1));
return directly, i.e.
return ad5758_spi...
> +
> + return ret;
> +}
> +
> +static int ad5758_probe(struct spi_device *spi)
> +{
> + struct ad5758_state *st;
> + struct iio_dev *indio_dev;
> + int ret;
> +
> + indio_dev = devm_iio_device_alloc(>dev, sizeof(*st));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + st = iio_priv(indio_dev);
> + spi_set_drvdata(spi, indio_dev);
> +
> + st->spi = spi;
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->name = spi_get_device_id(spi)->name;
> + indio_dev->info = _info;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->channels = ad5758_channels;
> + indio_dev->num_channels = ARRAY_SIZE(ad5758_channels);
> +
> + mutex_init(>lock);
> +
> + ret = ad5758_init(st);
> + if (ret < 0) {
> + dev_err(>dev, "AD5758 init failed\n");
> + return ret;
> + }
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(>dev, "Failed to register iio device\n");
is the message really necessary/likely?
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static const struct spi_device_id ad5758_id[] = {
> + { "ad5758", 0 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(spi, ad5758_id);
> +
> +static struct spi_driver ad5758_driver = {
> + .driver = {
> + .name = KBUILD_MODNAME,
> + },
> + .probe = ad5758_probe,
> + .id_table = ad5758_id,
> +};
> +
> +module_spi_driver(ad5758_driver);
> +
> +MODULE_AUTHOR("Stefan Popa ");
> +MODULE_DESCRIPTION("Analog Devices AD5758 DAC");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
if (ret < 0)
> + return ret;
> +
> + regval = ad5758_spi_reg_read(st, AD5758_DIGITAL_DIAG_RESULTS);
> + if (regval < 0)
> + return regval;
> +
> + /* Clear all the error flags */
> + ret = ad5758_spi_reg_write(st, AD5758_DIGITAL_DIAG_RESULTS, regval);
> + if (ret < 0)
> + return ret;
> +
> + /* Set the dc-to-dc current limit */
> + ret = ad5758_set_dc_dc_ilim(st, st->dc_dc_ilim);
> + if (ret < 0)
> + return ret;
> +
> + /* Configure the dc-to-dc controller mode */
> + ret = ad5758_set_dc_dc_conv_mode(st, st->dc_dc_mode);
> + if (ret < 0)
> + return ret;
> +
> + /* Configure the output range */
> + ret = ad5758_set_out_range(st, st->out_range);
> + if (ret < 0)
> + return ret;
> +
> + /* Enable Slew Rate Control, set the slew rate clock and step */
> + ret = ad5758_slew_rate_config(st, st->sr_config[0],
> + st->sr_config[1], st->sr_config[2]);
> + if (ret < 0)
> + return ret;
> +
> + /* Enable the VIOUT fault protection switch (FPS is closed) */
> + ret = ad5758_fault_prot_switch_en(st, 1);
> + if (ret < 0)
> + return ret;
> +
> + /* Power up the DAC and internal (INT) amplifiers */
> + ret = ad5758_internal_buffers_en(st, 1);
> + if (ret < 0)
> + return ret;
> +
> + /* Enable VIOUT */
> + ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
> + AD5758_DAC_CONFIG_OUT_EN_MSK,
> + AD5758_DAC_CONFIG_OUT_EN_MODE(1));
return directly, i.e.
return ad5758_spi...
> +
> + return ret;
> +}
> +
> +static int ad5758_probe(struct spi_device *spi)
> +{
> + struct ad5758_state *st;
> + struct iio_dev *indio_dev;
> + int ret;
> +
> + indio_dev = devm_iio_device_alloc(>dev, sizeof(*st));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + st = iio_priv(indio_dev);
> + spi_set_drvdata(spi, indio_dev);
> +
> + st->spi = spi;
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->name = spi_get_device_id(spi)->name;
> + indio_dev->info = _info;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->channels = ad5758_channels;
> + indio_dev->num_channels = ARRAY_SIZE(ad5758_channels);
> +
> + mutex_init(>lock);
> +
> + ret = ad5758_init(st);
> + if (ret < 0) {
> + dev_err(>dev, "AD5758 init failed\n");
> + return ret;
> + }
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(>dev, "Failed to register iio device\n");
is the message really necessary/likely?
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static const struct spi_device_id ad5758_id[] = {
> + { "ad5758", 0 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(spi, ad5758_id);
> +
> +static struct spi_driver ad5758_driver = {
> + .driver = {
> + .name = KBUILD_MODNAME,
> + },
> + .probe = ad5758_probe,
> + .id_table = ad5758_id,
> +};
> +
> +module_spi_driver(ad5758_driver);
> +
> +MODULE_AUTHOR("Stefan Popa ");
> +MODULE_DESCRIPTION("Analog Devices AD5758 DAC");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
minor comments below
> The AMS includes an ADC as well as on-chip sensors that can be used to
> sample external voltages and monitor on-die operating conditions, such as
> temperature and supply voltage levels. The AMS has two SYSMON blocks.
> PL-SYSMON block is capable of monitoring off chip
minor comments below
> The AMS includes an ADC as well as on-chip sensors that can be used to
> sample external voltages and monitor on-die operating conditions, such as
> temperature and supply voltage levels. The AMS has two SYSMON blocks.
> PL-SYSMON block is capable of monitoring off chip
return ret;
> +
> + tlv493d->factset1 = buf[7];
> + tlv493d->factset2 = buf[8];
> + tlv493d->factset3 = buf[9];
> +
> + buf[0] = 0;
> + buf[1] = MOD1_FAST | MOD1_LOW;
what does this mean? some comment explaining the default mode?
> + buf[2] = 0;
> + buf[3] = 0;
> + ret = tlv493d_write_regs(tlv493d, buf, 4);
> + if (ret)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(>dev, "device registration failed");
> + tlv493d_power_down(tlv493d);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int tlv493d_remove(struct i2c_client *i2c)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
> + struct tlv493d *tlv493d = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> +
> + tlv493d_power_down(tlv493d);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id tlv493d_dt_ids[] = {
> + { .compatible = "infineon,tlv493d-a1b6" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, tlv493d_dt_ids);
> +
> +static struct i2c_driver tlv493d_i2c_driver = {
> + .driver = {
> + .name = "tlv493d",
> + .of_match_table = tlv493d_dt_ids,
> + },
> + .probe_new = tlv493d_probe,
> + .remove = tlv493d_remove,
> +};
> +
> +module_i2c_driver(tlv493d_i2c_driver);
> +
> +MODULE_DESCRIPTION("TLV493D I2C driver");
> +MODULE_AUTHOR("Andreas Faerber");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
493d->factset2 = buf[8];
> + tlv493d->factset3 = buf[9];
> +
> + buf[0] = 0;
> + buf[1] = MOD1_FAST | MOD1_LOW;
what does this mean? some comment explaining the default mode?
> + buf[2] = 0;
> + buf[3] = 0;
> + ret = tlv493d_write_regs(tlv493d, buf, 4);
> + if (ret)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(>dev, "device registration failed");
> + tlv493d_power_down(tlv493d);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int tlv493d_remove(struct i2c_client *i2c)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
> + struct tlv493d *tlv493d = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> +
> + tlv493d_power_down(tlv493d);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id tlv493d_dt_ids[] = {
> + { .compatible = "infineon,tlv493d-a1b6" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, tlv493d_dt_ids);
> +
> +static struct i2c_driver tlv493d_i2c_driver = {
> + .driver = {
> + .name = "tlv493d",
> + .of_match_table = tlv493d_dt_ids,
> + },
> + .probe_new = tlv493d_probe,
> + .remove = tlv493d_remove,
> +};
> +
> +module_i2c_driver(tlv493d_i2c_driver);
> +
> +MODULE_DESCRIPTION("TLV493D I2C driver");
> +MODULE_AUTHOR("Andreas Faerber");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
uct iio_info sgp_info = {
> + .attrs = _attr_group,
> + .read_raw = sgp_read_raw,
> + .write_raw = sgp_write_raw,
> +};
> +
> +static const struct of_device_id sgp_dt_ids[] = {
> + { .compatible = "sensirion,sgp30", .data = (void *)SGP30 },
> + { .compatible = "sensirion,sgpc3", .data = (void *)SGPC3 },
> + { }
> +};
> +
> +static int sgp_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct iio_dev *indio_dev;
> + struct sgp_data *data;
> + struct sgp_device *chip;
> + const struct of_device_id *of_id;
> + unsigned long chip_id;
> + int ret;
> +
> + indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + of_id = of_match_device(sgp_dt_ids, >dev);
> + if (!of_id)
> + chip_id = id->driver_data;
> + else
> + chip_id = (unsigned long)of_id->data;
> +
> + chip = _devices[chip_id];
> + data = iio_priv(indio_dev);
> + i2c_set_clientdata(client, indio_dev);
> + data->client = client;
> + crc8_populate_msb(sgp_crc8_table, SGP_CRC8_POLYNOMIAL);
> + mutex_init(>data_lock);
> + mutex_init(>i2c_lock);
> +
> + /* get serial id and write it to client data */
> + ret = sgp_get_serial_id(data);
> +
> + if (ret != 0)
matter of taste: most drivers just do
if (ret)
> + return ret;
> +
> + /* get feature set version and write it to client data */
> + ret = sgp_read_from_cmd(data, SGP_CMD_GET_FEATURE_SET, 1,
> + SGP_CMD_DURATION_US);
> + if (ret != 0)
> + return ret;
> +
> + data->feature_set = be16_to_cpu(data->buffer.raw_words[0].value);
> +
> + ret = setup_and_check_sgp_data(data, chip_id);
> + if (ret < 0)
> + goto fail_free;
> +
> + /* so initial reading will complete */
> + data->last_update = jiffies - data->measure_interval_hz * HZ;
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->info = _info;
> + indio_dev->name = dev_name(>dev);
> + indio_dev->modes = INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE;
is INDIO_BUFFER_SOFTWARE implemented at this stage? maybe added in
followup patch
> +
> + indio_dev->channels = chip->channels;
> + indio_dev->num_channels = chip->num_channels;
> +
> + ret = devm_iio_device_register(>dev, indio_dev);
> + if (!ret)
> + return ret;
> +
> + dev_err(>dev, "failed to register iio device\n");
really message needed?
> +
> +fail_free:
> + mutex_destroy(>i2c_lock);
> + mutex_destroy(>data_lock);
no need to explicitly destroy mutex
> + iio_device_free(indio_dev);
no need to explicitly free devm_ stuff
> + return ret;
> +}
> +
> +static int sgp_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + devm_iio_device_unregister(>dev, indio_dev);
not needed
> + return 0;
> +}
> +
> +static const struct i2c_device_id sgp_id[] = {
> + { "sgp30", SGP30 },
> + { "sgpc3", SGPC3 },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, sgp_id);
> +MODULE_DEVICE_TABLE(of, sgp_dt_ids);
> +
> +static struct i2c_driver sgp_driver = {
> + .driver = {
> + .name = "sgpxx",
> + .of_match_table = of_match_ptr(sgp_dt_ids),
> + },
> + .probe = sgp_probe,
> + .remove = sgp_remove,
> + .id_table = sgp_id,
> +};
> +module_i2c_driver(sgp_driver);
> +
> +MODULE_AUTHOR("Andreas Brauchli <andreas.brauc...@sensirion.com>");
> +MODULE_AUTHOR("Pascal Sachs <pascal.sa...@sensirion.com>");
> +MODULE_DESCRIPTION("Sensirion SGPxx gas sensors");
> +MODULE_LICENSE("GPL v2");
> +MODULE_VERSION("0.5.0");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
gt; + _dev_attr_out_iaq_baseline.dev_attr.attr,
> + NULL
> +};
> +
> +static const struct attribute_group sgp_attr_group = {
> + .attrs = sgp_attributes,
> +};
> +
> +static const struct iio_info sgp_info = {
> + .attrs = _attr_group,
> + .read_raw = sgp_read_raw,
> + .write_raw = sgp_write_raw,
> +};
> +
> +static const struct of_device_id sgp_dt_ids[] = {
> + { .compatible = "sensirion,sgp30", .data = (void *)SGP30 },
> + { .compatible = "sensirion,sgpc3", .data = (void *)SGPC3 },
> + { }
> +};
> +
> +static int sgp_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct iio_dev *indio_dev;
> + struct sgp_data *data;
> + struct sgp_device *chip;
> + const struct of_device_id *of_id;
> + unsigned long chip_id;
> + int ret;
> +
> + indio_dev = devm_iio_device_alloc(>dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + of_id = of_match_device(sgp_dt_ids, >dev);
> + if (!of_id)
> + chip_id = id->driver_data;
> + else
> + chip_id = (unsigned long)of_id->data;
> +
> + chip = _devices[chip_id];
> + data = iio_priv(indio_dev);
> + i2c_set_clientdata(client, indio_dev);
> + data->client = client;
> + crc8_populate_msb(sgp_crc8_table, SGP_CRC8_POLYNOMIAL);
> + mutex_init(>data_lock);
> + mutex_init(>i2c_lock);
> +
> + /* get serial id and write it to client data */
> + ret = sgp_get_serial_id(data);
> +
> + if (ret != 0)
matter of taste: most drivers just do
if (ret)
> + return ret;
> +
> + /* get feature set version and write it to client data */
> + ret = sgp_read_from_cmd(data, SGP_CMD_GET_FEATURE_SET, 1,
> + SGP_CMD_DURATION_US);
> + if (ret != 0)
> + return ret;
> +
> + data->feature_set = be16_to_cpu(data->buffer.raw_words[0].value);
> +
> + ret = setup_and_check_sgp_data(data, chip_id);
> + if (ret < 0)
> + goto fail_free;
> +
> + /* so initial reading will complete */
> + data->last_update = jiffies - data->measure_interval_hz * HZ;
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->info = _info;
> + indio_dev->name = dev_name(>dev);
> + indio_dev->modes = INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE;
is INDIO_BUFFER_SOFTWARE implemented at this stage? maybe added in
followup patch
> +
> + indio_dev->channels = chip->channels;
> + indio_dev->num_channels = chip->num_channels;
> +
> + ret = devm_iio_device_register(>dev, indio_dev);
> + if (!ret)
> + return ret;
> +
> + dev_err(>dev, "failed to register iio device\n");
really message needed?
> +
> +fail_free:
> + mutex_destroy(>i2c_lock);
> + mutex_destroy(>data_lock);
no need to explicitly destroy mutex
> + iio_device_free(indio_dev);
no need to explicitly free devm_ stuff
> + return ret;
> +}
> +
> +static int sgp_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + devm_iio_device_unregister(>dev, indio_dev);
not needed
> + return 0;
> +}
> +
> +static const struct i2c_device_id sgp_id[] = {
> + { "sgp30", SGP30 },
> + { "sgpc3", SGPC3 },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, sgp_id);
> +MODULE_DEVICE_TABLE(of, sgp_dt_ids);
> +
> +static struct i2c_driver sgp_driver = {
> + .driver = {
> + .name = "sgpxx",
> + .of_match_table = of_match_ptr(sgp_dt_ids),
> + },
> + .probe = sgp_probe,
> + .remove = sgp_remove,
> + .id_table = sgp_id,
> +};
> +module_i2c_driver(sgp_driver);
> +
> +MODULE_AUTHOR("Andreas Brauchli ");
> +MODULE_AUTHOR("Pascal Sachs ");
> +MODULE_DESCRIPTION("Sensirion SGPxx gas sensors");
> +MODULE_LICENSE("GPL v2");
> +MODULE_VERSION("0.5.0");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
/
> case IIO_VAL_INT_PLUS_MICRO:
> if (vals[1] < 0)
> return snprintf(buf, len, "-%d.%06u%s", abs(vals[0]),
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
case IIO_VAL_INT_PLUS_MICRO:
> if (vals[1] < 0)
> return snprintf(buf, len, "-%d.%06u%s", abs(vals[0]),
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct cm32181_chip *cm32181 = iio_priv(indio_dev);
> +
> + if (cm32181->ara)
> + i2c_unregister_device(cm32181->ara);
> +
> + return 0;
> +};
> +
> static const struct i2c_device_id cm32181_id[] = {
> - { "cm32181", 0 },
> + { "cm32181", CM32181_ID },
> + { "cm3218", CM3218_ID },
> { }
> };
>
> MODULE_DEVICE_TABLE(i2c, cm32181_id);
>
> static const struct of_device_id cm32181_of_match[] = {
> - { .compatible = "capella,cm32181" },
> + { .compatible = "capella,cm32181", (void *)CM32181_ID },
> + { .compatible = "capella,cm3218", (void *)CM3218_ID },
> { }
> };
> MODULE_DEVICE_TABLE(of, cm32181_of_match);
>
> +static const struct acpi_device_id cm32181_acpi_match[] = {
> + { "CPLM3218", CM3218_ID },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(acpi, cm32181_acpi_match);
> +
> static struct i2c_driver cm32181_driver = {
> .driver = {
> .name = "cm32181",
> .of_match_table = of_match_ptr(cm32181_of_match),
> + .acpi_match_table = ACPI_PTR(cm32181_acpi_match),
> },
> .id_table = cm32181_id,
> .probe = cm32181_probe,
> + .remove = cm32181_remove,
> };
>
> module_i2c_driver(cm32181_driver);
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
ient)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct cm32181_chip *cm32181 = iio_priv(indio_dev);
> +
> + if (cm32181->ara)
> + i2c_unregister_device(cm32181->ara);
> +
> + return 0;
> +};
> +
> static const struct i2c_device_id cm32181_id[] = {
> - { "cm32181", 0 },
> + { "cm32181", CM32181_ID },
> + { "cm3218", CM3218_ID },
> { }
> };
>
> MODULE_DEVICE_TABLE(i2c, cm32181_id);
>
> static const struct of_device_id cm32181_of_match[] = {
> - { .compatible = "capella,cm32181" },
> + { .compatible = "capella,cm32181", (void *)CM32181_ID },
> + { .compatible = "capella,cm3218", (void *)CM3218_ID },
> { }
> };
> MODULE_DEVICE_TABLE(of, cm32181_of_match);
>
> +static const struct acpi_device_id cm32181_acpi_match[] = {
> + { "CPLM3218", CM3218_ID },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(acpi, cm32181_acpi_match);
> +
> static struct i2c_driver cm32181_driver = {
> .driver = {
> .name = "cm32181",
> .of_match_table = of_match_ptr(cm32181_of_match),
> + .acpi_match_table = ACPI_PTR(cm32181_acpi_match),
> },
> .id_table = cm32181_id,
> .probe = cm32181_probe,
> + .remove = cm32181_remove,
> };
>
> module_i2c_driver(cm32181_driver);
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
t; If it leads to more complex flow as here, don't do it.
>
> I would appreciate to clarify such a view a bit more.
> How would you like to achieve a complete and efficient
> exception handling in shown places?
regards, p.
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
t; If it leads to more complex flow as here, don't do it.
>
> I would appreciate to clarify such a view a bit more.
> How would you like to achieve a complete and efficient
> exception handling in shown places?
regards, p.
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
_ID },
> { }
> };
>
> MODULE_DEVICE_TABLE(i2c, cm32181_id);
>
> static const struct of_device_id cm32181_of_match[] = {
> - { .compatible = "capella,cm32181" },
> + { .compatible = "capella,cm32181", (void *)CM32181_ID },
> + { .compatible = "capella,cm3218", (void *)CM3218_ID },
> { }
> };
> MODULE_DEVICE_TABLE(of, cm32181_of_match);
>
> +static const struct acpi_device_id cm32181_acpi_match[] = {
> + { "CPLM3218", CM3218_ID },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(acpi, cm32181_acpi_match);
> +
> static struct i2c_driver cm32181_driver = {
> .driver = {
> .name = "cm32181",
> .of_match_table = of_match_ptr(cm32181_of_match),
> + .acpi_match_table = ACPI_PTR(cm32181_acpi_match),
> },
> .id_table = cm32181_id,
> .probe = cm32181_probe,
> + .remove = cm32181_remove,
> };
>
> module_i2c_driver(cm32181_driver);
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
ster_device(cm32181->ara);
> +
> + return 0;
> +};
> +
> static const struct i2c_device_id cm32181_id[] = {
> - { "cm32181", 0 },
> + { "cm32181", CM32181_ID },
> + { "cm3218", CM3218_ID },
> { }
> };
>
&g
if (chan->type != IIO_LIGHT)
> return -EINVAL;
>
> return vl6180_set_als_gain(data, val, val2);
> +
> default:
> return -EINVAL;
> }
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
(chan->type != IIO_LIGHT)
> return -EINVAL;
>
> return vl6180_set_als_gain(data, val, val2);
> +
> default:
> return -EINVAL;
> }
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
return -EINVAL;
> + ret = vl6180_write_byte(data->client, VL6180_ALS_GAIN,
> + vl6180_als_gain_tab_bits[i]);
> +
> + if (ret >= 0)
> + data->als_gain_milli = vl6180_als_gain_tab[i];
> +
> +fail:
> + vl6180_hold(data, false);
> + mutex_unlock(>lock);
> + return ret;
> }
>
> static int vl6180_set_it(struct vl6180_data *data, int val, int val2)
> @@ -480,6 +482,7 @@ static int vl6180_init(struct vl6180_data *data)
> return ret;
>
> /* ALS gain: 1 */
> + data->als_gain_milli = 1000;
> ret = vl6180_write_byte(client, VL6180_ALS_GAIN, VL6180_ALS_GAIN_1);
> if (ret < 0)
> return ret;
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
= vl6180_write_byte(data->client, VL6180_ALS_GAIN,
> + vl6180_als_gain_tab_bits[i]);
> +
> + if (ret >= 0)
> + data->als_gain_milli = vl6180_als_gain_tab[i];
> +
> +fail:
> + vl6180_hold(data, false);
> + mutex_unlock(>lock);
> + return ret;
> }
>
> static int vl6180_set_it(struct vl6180_data *data, int val, int val2)
> @@ -480,6 +482,7 @@ static int vl6180_init(struct vl6180_data *data)
> return ret;
>
> /* ALS gain: 1 */
> + data->als_gain_milli = 1000;
> ret = vl6180_write_byte(client, VL6180_ALS_GAIN, VL6180_ALS_GAIN_1);
> if (ret < 0)
> return ret;
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
"ds4424: Invalid chip id.\n");
> + regulator_disable(data->vcc_reg);
> + return -ENXIO;
> + }
> +
> + indio_dev->channels = ds4424_channels;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + dev_err(>dev,
> + "iio_device_register failed. ret: %d\n", ret);
> + regulator_disable(data->vcc_reg);
> + }
> +
> + return ret;
> +}
> +
> +static int ds4424_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct ds4424_data *data = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> + regulator_disable(data->vcc_reg);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id ds4424_id[] = {
> + { "ds4422", ID_DS4422 },
> + { "ds4424", ID_DS4424 },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, ds4424_id);
> +
> +static const struct of_device_id ds4424_of_match[] = {
> + { .compatible = "maxim,ds4422" },
> + { .compatible = "maxim,ds4424" },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(of, ds4424_of_match);
> +
> +static struct i2c_driver ds4424_driver = {
> + .driver = {
> + .name = "ds4424",
> + .of_match_table = ds4424_of_match,
> + .pm = _pm_ops,
> + },
> + .probe = ds4424_probe,
> + .remove = ds4424_remove,
> + .id_table = ds4424_id,
> +};
> +module_i2c_driver(ds4424_driver);
> +
> +MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
> +MODULE_AUTHOR("Ismail H. Kose <ismail.k...@maximintegrated.com>");
> +MODULE_AUTHOR("Vishal Sood <vishal.s...@maximintegrated.com>");
> +MODULE_AUTHOR("David Jung <david.j...@maximintegrated.com>");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
4424: Invalid chip id.\n");
> + regulator_disable(data->vcc_reg);
> + return -ENXIO;
> + }
> +
> + indio_dev->channels = ds4424_channels;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + dev_err(>dev,
> + "iio_device_register failed. ret: %d\n", ret);
> + regulator_disable(data->vcc_reg);
> + }
> +
> + return ret;
> +}
> +
> +static int ds4424_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct ds4424_data *data = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> + regulator_disable(data->vcc_reg);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id ds4424_id[] = {
> + { "ds4422", ID_DS4422 },
> + { "ds4424", ID_DS4424 },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, ds4424_id);
> +
> +static const struct of_device_id ds4424_of_match[] = {
> + { .compatible = "maxim,ds4422" },
> + { .compatible = "maxim,ds4424" },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(of, ds4424_of_match);
> +
> +static struct i2c_driver ds4424_driver = {
> + .driver = {
> + .name = "ds4424",
> + .of_match_table = ds4424_of_match,
> + .pm = _pm_ops,
> + },
> + .probe = ds4424_probe,
> + .remove = ds4424_remove,
> + .id_table = ds4424_id,
> +};
> +module_i2c_driver(ds4424_driver);
> +
> +MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
> +MODULE_AUTHOR("Ismail H. Kose ");
> +MODULE_AUTHOR("Vishal Sood ");
> +MODULE_AUTHOR("David Jung ");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
9 @@ static int inv_mpu6050_write_raw(struct iio_dev
> *indio_dev,
> break;
> default:
> result = -EINVAL;
> + break;
> }
> + break;
> default:
> result = -EINVAL;
> break;
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
tatic int inv_mpu6050_write_raw(struct iio_dev
> *indio_dev,
> break;
> default:
> result = -EINVAL;
> + break;
> }
> + break;
> default:
> result = -EINVAL;
> break;
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> From: Abhisit Sangjan
>
> TI LMP92001 Analog System Monitor and Controller
some minor comments, not a full review
> 8-bit GPIOs.
> 12 DACs with 12-bit resolution.
> The GPIOs and DACs are shared port function with Cy function pin to
> take control the pin suddenly from
> From: Abhisit Sangjan
>
> TI LMP92001 Analog System Monitor and Controller
some minor comments, not a full review
> 8-bit GPIOs.
> 12 DACs with 12-bit resolution.
> The GPIOs and DACs are shared port function with Cy function pin to
> take control the pin suddenly from external hardware.
>
return ret;
> + }
> +
> /*
>* set default values of device here
>* these register values cannot be read from the hardware
> @@ -402,5 +455,5 @@ static struct i2c_driver srf08_driver = {
> module_i2c_driver(srf08_driver);
>
> MODULE_AUTHOR("Andreas Klinger <a...@it-klinger.de>");
> -MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver");
> +MODULE_DESCRIPTION("Devantech SRF08/SRF10 ultrasonic ranger driver");
> MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> +
> /*
>* set default values of device here
> * these register values cannot be read from the hardware
> @@ -402,5 +455,5 @@ static struct i2c_driver srf08_driver = {
> module_i2c_driver(srf08_driver);
>
> MODULE_AUTHOR("Andreas Klinger ");
> -MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver");
> +MODULE_DESCRIPTION("Devantech SRF08/SRF10 ultrasonic ranger driver");
> MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
id *)SRF08},
> { .compatible = "devantech,srf10", (void *)SRF10},
> {},
> @@ -473,6 +511,7 @@ static const struct of_device_id of_srf08_match[] = {
> MODULE_DEVICE_TABLE(of, of_srf08_match);
>
> static const struct i2c_device_id srf08_id[] = {
> + { "srf02", SRF02 },
> { "srf08", SRF08 },
> { "srf10", SRF10 },
> { }
> @@ -490,5 +529,5 @@ static struct i2c_driver srf08_driver = {
> module_i2c_driver(srf08_driver);
>
> MODULE_AUTHOR("Andreas Klinger <a...@it-klinger.de>");
> -MODULE_DESCRIPTION("Devantech SRF08/SRF10 ultrasonic ranger driver");
> +MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger
> driver");
> MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
dev, indio_dev);
> }
>
> static const struct of_device_id of_srf08_match[] = {
> + { .compatible = "devantech,srf02", (void *)SRF02},
> { .compatible = "devantech,srf08", (void *)SRF08},
> { .compatible = "devantech,srf10", (void *
s = { {0, 9577}, {0, 19154}, {0, 38307} },
> - .ev_cfg = MMA8452_FF_MT_CFG,
> - .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE,
> - .ev_cfg_chan_shift = 3,
> - .ev_src = MMA8452_FF_MT_SRC,
> - .ev_src_xe = MMA8452_FF_MT_SRC_XHE,
> - .ev_src_ye = MMA8452_FF_MT_SRC_YHE,
> - .ev_src_ze = MMA8452_FF_MT_SRC_ZHE,
> - .ev_ths = MMA8452_FF_MT_THS,
> - .ev_ths_mask = MMA8452_FF_MT_THS_MASK,
> - .ev_count = MMA8452_FF_MT_COUNT,
> },
> [mma8653] = {
> .chip_id = MMA8653_DEVICE_ID,
> .channels = mma8653_channels,
> .num_channels = ARRAY_SIZE(mma8653_channels),
> .mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} },
> - .ev_cfg = MMA8452_FF_MT_CFG,
> - .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE,
> - .ev_cfg_chan_shift = 3,
> - .ev_src = MMA8452_FF_MT_SRC,
> - .ev_src_xe = MMA8452_FF_MT_SRC_XHE,
> - .ev_src_ye = MMA8452_FF_MT_SRC_YHE,
> - .ev_src_ze = MMA8452_FF_MT_SRC_ZHE,
> - .ev_ths = MMA8452_FF_MT_THS,
> - .ev_ths_mask = MMA8452_FF_MT_THS_MASK,
> - .ev_count = MMA8452_FF_MT_COUNT,
> },
> [fxls8471] = {
> .chip_id = FXLS8471_DEVICE_ID,
> .channels = mma8451_channels,
> .num_channels = ARRAY_SIZE(mma8451_channels),
> .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} },
> - .ev_cfg = MMA8452_TRANSIENT_CFG,
> - .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE,
> - .ev_cfg_chan_shift = 1,
> - .ev_src = MMA8452_TRANSIENT_SRC,
> - .ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE,
> - .ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE,
> - .ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE,
> - .ev_ths = MMA8452_TRANSIENT_THS,
> - .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK,
> - .ev_count = MMA8452_TRANSIENT_COUNT,
> },
> };
>
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
38307} },
> - .ev_cfg = MMA8452_FF_MT_CFG,
> - .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE,
> - .ev_cfg_chan_shift = 3,
> - .ev_src = MMA8452_FF_MT_SRC,
> - .ev_src_xe = MMA8452_FF_MT_SRC_XHE,
> - .ev_src_ye = MMA8452_FF_MT_SRC_YHE,
> - .ev_src_ze = MMA8452_FF_MT_SRC_ZHE,
> - .ev_ths = MMA8452_FF_MT_THS,
> - .ev_ths_mask = MMA8452_FF_MT_THS_MASK,
> - .ev_count = MMA8452_FF_MT_COUNT,
> },
> [mma8653] = {
> .chip_id = MMA8653_DEVICE_ID,
> .channels = mma8653_channels,
> .num_channels = ARRAY_SIZE(mma8653_channels),
> .mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} },
> - .ev_cfg = MMA8452_FF_MT_CFG,
> - .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE,
> - .ev_cfg_chan_shift = 3,
> - .ev_src = MMA8452_FF_MT_SRC,
> - .ev_src_xe = MMA8452_FF_MT_SRC_XHE,
> - .ev_src_ye = MMA8452_FF_MT_SRC_YHE,
> - .ev_src_ze = MMA8452_FF_MT_SRC_ZHE,
> - .ev_ths = MMA8452_FF_MT_THS,
> - .ev_ths_mask = MMA8452_FF_MT_THS_MASK,
> - .ev_count = MMA8452_FF_MT_COUNT,
> },
> [fxls8471] = {
> .chip_id = FXLS8471_DEVICE_ID,
> .channels = mma8451_channels,
> .num_channels = ARRAY_SIZE(mma8451_channels),
> .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} },
> - .ev_cfg = MMA8452_TRANSIENT_CFG,
> - .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE,
> - .ev_cfg_chan_shift = 1,
> - .ev_src = MMA8452_TRANSIENT_SRC,
> - .ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE,
> - .ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE,
> - .ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE,
> - .ev_ths = MMA8452_TRANSIENT_THS,
> - .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK,
> - .ev_count = MMA8452_TRANSIENT_COUNT,
> },
> };
>
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
LMP92001_CAD3, 1, cad3);
> +if (ret < 0)
> +{
> +dev_err(>dev, "failed to enable channel 17
> (temperature)\n");
> +return ret;
> +}
> +
> + ret = of_property_read_string_index(np, "ti,lmp92001-adc-mode", 0,
> +);
> +if (!ret)
> +{
> +if (strcmp("continuous", conversion) == 0)
> +cgen |= 1;
> +else if (strcmp("single-shot", conversion) == 0)
> +{ /* Okay */ }
> +else
> +dev_warn(>dev,
> +"wrong adc mode! set to single-short conversion\n");
> +}
> +else
> +dev_info(>dev,
> +"single-short conversion was chosen by default\n");
> +
> +/*
> + * Lock the registers and set conversion mode.
> + */
> +ret = regmap_update_bits(lmp92001->regmap,
> +LMP92001_CGEN, 3, cgen | 2);
> +if (ret < 0)
> +return ret;
> +
> +platform_set_drvdata(pdev, indio_dev);
> +
> +return iio_device_register(indio_dev);
> +}
> +
> +static int lmp92001_adc_remove(struct platform_device *pdev)
> +{
> +struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +iio_device_unregister(indio_dev);
> +
> +return 0;
> +}
> +
> +static struct platform_driver lmp92001_adc_driver = {
> +.driver.name= "lmp92001-adc",
> +.driver.owner = THIS_MODULE,
> +.probe = lmp92001_adc_probe,
> +.remove = lmp92001_adc_remove,
> +};
> +
> +static int __init lmp92001_adc_init(void)
> +{
> +return platform_driver_register(_adc_driver);
> +}
> +subsys_initcall(lmp92001_adc_init);
> +
> +static void __exit lmp92001_adc_exit(void)
> +{
> +platform_driver_unregister(_adc_driver);
> +}
> +module_exit(lmp92001_adc_exit);
> +
> +MODULE_AUTHOR("Abhisit Sangjan <s.abhi...@gmail.com>");
> +MODULE_DESCRIPTION("IIO ADC interface for TI LMP92001");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:lmp92001-adc");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
; +dev_err(>dev, "failed to enable channel 17
> (temperature)\n");
> +return ret;
> +}
> +
> + ret = of_property_read_string_index(np, "ti,lmp92001-adc-mode", 0,
> +);
> +if (!ret)
> +{
> +if (strcmp("continuous", conversion) == 0)
> +cgen |= 1;
> +else if (strcmp("single-shot", conversion) == 0)
> +{ /* Okay */ }
> +else
> +dev_warn(>dev,
> +"wrong adc mode! set to single-short conversion\n");
> +}
> +else
> +dev_info(>dev,
> +"single-short conversion was chosen by default\n");
> +
> +/*
> + * Lock the registers and set conversion mode.
> + */
> +ret = regmap_update_bits(lmp92001->regmap,
> +LMP92001_CGEN, 3, cgen | 2);
> +if (ret < 0)
> +return ret;
> +
> +platform_set_drvdata(pdev, indio_dev);
> +
> +return iio_device_register(indio_dev);
> +}
> +
> +static int lmp92001_adc_remove(struct platform_device *pdev)
> +{
> +struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +iio_device_unregister(indio_dev);
> +
> +return 0;
> +}
> +
> +static struct platform_driver lmp92001_adc_driver = {
> +.driver.name= "lmp92001-adc",
> +.driver.owner = THIS_MODULE,
> +.probe = lmp92001_adc_probe,
> +.remove = lmp92001_adc_remove,
> +};
> +
> +static int __init lmp92001_adc_init(void)
> +{
> +return platform_driver_register(_adc_driver);
> +}
> +subsys_initcall(lmp92001_adc_init);
> +
> +static void __exit lmp92001_adc_exit(void)
> +{
> +platform_driver_unregister(_adc_driver);
> +}
> +module_exit(lmp92001_adc_exit);
> +
> +MODULE_AUTHOR("Abhisit Sangjan ");
> +MODULE_DESCRIPTION("IIO ADC interface for TI LMP92001");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:lmp92001-adc");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
of_property_read_u8(np, "ti,lmp92001-dac-outx", );
> +cdac |= outx << 1;
> +
> + of_property_read_u8(np, "ti,lmp92001-dac-gang", );
> +cdac |= gang << 2;
> +
> +ret = regmap_update_bits(lmp92001->regmap, LMP92001_CDAC, 7, cdac);
> +if (ret < 0)
> +return ret;
> +
> +platform_set_drvdata(pdev, indio_dev);
> +
> +return iio_device_register(indio_dev);
> +}
> +
> +static int lmp92001_dac_remove(struct platform_device *pdev)
can use devm_iio_device_register() if _remove() is essentially empty
> +{
> +struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +iio_device_unregister(indio_dev);
> +
> +return 0;
> +}
> +
> +static struct platform_driver lmp92001_dac_driver = {
> +.driver.name= "lmp92001-dac",
> +.driver.owner = THIS_MODULE,
> +.probe = lmp92001_dac_probe,
THIS_MODULE not needed anymore
> +.remove = lmp92001_dac_remove,
> +};
> +
> +static int __init lmp92001_dac_init(void)
> +{
> +return platform_driver_register(_dac_driver);
> +}
> +subsys_initcall(lmp92001_dac_init);
> +
> +static void __exit lmp92001_dac_exit(void)
> +{
> +platform_driver_unregister(_dac_driver);
> +}
> +module_exit(lmp92001_dac_exit);
> +
> +MODULE_AUTHOR("Abhisit Sangjan <s.abhi...@gmail.com>");
> +MODULE_DESCRIPTION("IIO DAC interface for TI LMP92001");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:lmp92001-dac");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
);
> +cdac |= outx << 1;
> +
> +of_property_read_u8(np, "ti,lmp92001-dac-gang", );
> +cdac |= gang << 2;
> +
> +ret = regmap_update_bits(lmp92001->regmap, LMP92001_CDAC, 7, cdac);
> +if (ret < 0)
> +return ret;
> +
> +platform_set_drvdata(pdev, indio_dev);
> +
> +return iio_device_register(indio_dev);
> +}
> +
> +static int lmp92001_dac_remove(struct platform_device *pdev)
can use devm_iio_device_register() if _remove() is essentially empty
> +{
> +struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +iio_device_unregister(indio_dev);
> +
> +return 0;
> +}
> +
> +static struct platform_driver lmp92001_dac_driver = {
> +.driver.name= "lmp92001-dac",
> +.driver.owner = THIS_MODULE,
> +.probe = lmp92001_dac_probe,
THIS_MODULE not needed anymore
> +.remove = lmp92001_dac_remove,
> +};
> +
> +static int __init lmp92001_dac_init(void)
> +{
> +return platform_driver_register(_dac_driver);
> +}
> +subsys_initcall(lmp92001_dac_init);
> +
> +static void __exit lmp92001_dac_exit(void)
> +{
> +platform_driver_unregister(_dac_driver);
> +}
> +module_exit(lmp92001_dac_exit);
> +
> +MODULE_AUTHOR("Abhisit Sangjan ");
> +MODULE_DESCRIPTION("IIO DAC interface for TI LMP92001");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:lmp92001-dac");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
"Cannot read from device.\n");
> + return ret;
> + }
> +
> + return devm_iio_device_register(>dev, indio_dev);
> +}
> +
> +static const struct i2c_device_id ltc2471_i2c_id[] = {
> + { "ltc2471", ltc2471 },
> + { "ltc2473", ltc2473 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, ltc2471_i2c_id);
> +
> +static struct i2c_driver ltc2471_i2c_driver = {
> + .driver = {
> + .name = "ltc2471",
> + },
> + .probe= ltc2471_i2c_probe,
> + .id_table = ltc2471_i2c_id,
> +};
> +
> +module_i2c_driver(ltc2471_i2c_driver);
> +
> +MODULE_DESCRIPTION("LTC2471/LTC2473 Sensor Driver");
maybe "ADC driver"
> +MODULE_AUTHOR("Topic Embedded Products");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
c2471_channel;
> + indio_dev->num_channels = 1;
> +
> + /* Trigger once to start conversion and check if chip is there */
> + ret = ltc2471_get_value(client);
> + if (ret < 0) {
> + dev_err(>dev, "Cannot read from device.\n");
> + return r
gt; + }
> +
> + mutex_init(>lock);
> + ret = ds4424_regulator_onoff(indio_dev, PWR_ON);
> + if (ret < 0) {
> + pr_err("Unable to turn on the regulator. %s:%d, ret: %d\n",
> + __func__, __LINE__, ret);
> + return ret;
> + }
> +
> + switch (id->driver_data) {
> + case ID_DS4422:
> + indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
> + break;
> + case ID_DS4424:
> + indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
> + break;
> + default:
> + indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
> + break;
> + }
> +
> + indio_dev->channels = ds4424_channels;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> +
> + ret = iio_map_array_register(indio_dev, data->dac_iio_map);
> + if (ret < 0)
> + goto err_iio_device_0;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + pr_err("iio_device_register failed . %s:%d, ret: %d\n",
delete space after 'failed'
> + __func__, __LINE__, ret);
> + goto err_iio_device_1;
> + }
> +
> + return ret;
> +
> +err_iio_device_0:
> + ds4424_regulator_onoff(indio_dev, PWR_OFF);
> +err_iio_device_1:
> + iio_map_array_unregister(indio_dev);
> + return ret;
> +}
> +
> +static int ds4424_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> + iio_map_array_unregister(indio_dev);
> + ds4424_regulator_onoff(indio_dev, PWR_OFF);
> + return 0;
> +}
> +
> +static const struct i2c_device_id ds4424_id[] = {
> + { "ds4422", ID_DS4422 },
> + { "ds4424", ID_DS4424 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, ds4424_id);
> +
> +static const struct of_device_id ds4424_of_match[] = {
> + { .compatible = "maxim,ds4422" },
> + { .compatible = "maxim,ds4424" },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(of, ds4424_of_match);
> +
> +static struct i2c_driver ds4424_driver = {
> + .driver = {
> + .name = "ds4424",
> + .pm = DS4424_PM_OPS,
> + },
> + .probe = ds4424_probe,
> + .remove = ds4424_remove,
> + .id_table = ds4424_id,
> +};
> +module_i2c_driver(ds4424_driver);
> +
> +MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
> +MODULE_AUTHOR("Ismail H. Kose <ismail.k...@maximintegrated.com>");
> +MODULE_AUTHOR("Vishal Sood <vishal.s...@maximintegrated.com>");
> +MODULE_AUTHOR("David Jung <david.j...@maximintegrated.com>");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/iio/dac/ds4424.h b/include/linux/iio/dac/ds4424.h
> new file mode 100644
> index ..09ff3d61797d
> --- /dev/null
> +++ b/include/linux/iio/dac/ds4424.h
> @@ -0,0 +1,29 @@
> +/*
> + * Maxim Integrated
> + * 7-bit, Multi-Channel Sink/Source Current DAC Driver
> + * Copyright (C) 2017 Maxim Integrated
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef IIO_DAC_DS4424_H_
> +#define IIO_DAC_DS4424_H_
> +#include
> +#include
> +
> +#define DS4422_MAX_DAC_CHANNELS 2
> +#define DS4424_MAX_DAC_CHANNELS 4
> +#define DS442X_MAX_DAC_CHANNELS DS4424_MAX_DAC_CHANNELS
> +
> +struct ds4424_pdata {
> + const char *vcc_supply_name;
> + uint32_t max_rfs;
> + uint32_t min_rfs;
> + uint32_t ifs_scale;
> + uint32_t max_picoamp;
> + uint32_t rfs_res[DS442X_MAX_DAC_CHANNELS];
> + struct iio_map dac_iio_map[DS442X_MAX_DAC_CHANNELS + 1];
> +};
> +#endif /* IIO_DAC_DS4424_H_ */
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
_init(>lock);
> + ret = ds4424_regulator_onoff(indio_dev, PWR_ON);
> + if (ret < 0) {
> + pr_err("Unable to turn on the regulator. %s:%d, ret: %d\n",
> + __func__, __LINE__, ret);
> + return ret;
> + }
> +
> + switch (id->driver_data) {
> + case ID_DS4422:
> + indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
> + break;
> + case ID_DS4424:
> + indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
> + break;
> + default:
> + indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
> + break;
> + }
> +
> + indio_dev->channels = ds4424_channels;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> +
> + ret = iio_map_array_register(indio_dev, data->dac_iio_map);
> + if (ret < 0)
> + goto err_iio_device_0;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + pr_err("iio_device_register failed . %s:%d, ret: %d\n",
delete space after 'failed'
> + __func__, __LINE__, ret);
> + goto err_iio_device_1;
> + }
> +
> + return ret;
> +
> +err_iio_device_0:
> + ds4424_regulator_onoff(indio_dev, PWR_OFF);
> +err_iio_device_1:
> + iio_map_array_unregister(indio_dev);
> + return ret;
> +}
> +
> +static int ds4424_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> + iio_map_array_unregister(indio_dev);
> + ds4424_regulator_onoff(indio_dev, PWR_OFF);
> + return 0;
> +}
> +
> +static const struct i2c_device_id ds4424_id[] = {
> + { "ds4422", ID_DS4422 },
> + { "ds4424", ID_DS4424 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, ds4424_id);
> +
> +static const struct of_device_id ds4424_of_match[] = {
> + { .compatible = "maxim,ds4422" },
> + { .compatible = "maxim,ds4424" },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(of, ds4424_of_match);
> +
> +static struct i2c_driver ds4424_driver = {
> + .driver = {
> + .name = "ds4424",
> + .pm = DS4424_PM_OPS,
> + },
> + .probe = ds4424_probe,
> + .remove = ds4424_remove,
> + .id_table = ds4424_id,
> +};
> +module_i2c_driver(ds4424_driver);
> +
> +MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
> +MODULE_AUTHOR("Ismail H. Kose ");
> +MODULE_AUTHOR("Vishal Sood ");
> +MODULE_AUTHOR("David Jung ");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/iio/dac/ds4424.h b/include/linux/iio/dac/ds4424.h
> new file mode 100644
> index ..09ff3d61797d
> --- /dev/null
> +++ b/include/linux/iio/dac/ds4424.h
> @@ -0,0 +1,29 @@
> +/*
> + * Maxim Integrated
> + * 7-bit, Multi-Channel Sink/Source Current DAC Driver
> + * Copyright (C) 2017 Maxim Integrated
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef IIO_DAC_DS4424_H_
> +#define IIO_DAC_DS4424_H_
> +#include
> +#include
> +
> +#define DS4422_MAX_DAC_CHANNELS 2
> +#define DS4424_MAX_DAC_CHANNELS 4
> +#define DS442X_MAX_DAC_CHANNELS DS4424_MAX_DAC_CHANNELS
> +
> +struct ds4424_pdata {
> + const char *vcc_supply_name;
> + uint32_t max_rfs;
> + uint32_t min_rfs;
> + uint32_t ifs_scale;
> + uint32_t max_picoamp;
> + uint32_t rfs_res[DS442X_MAX_DAC_CHANNELS];
> + struct iio_map dac_iio_map[DS442X_MAX_DAC_CHANNELS + 1];
> +};
> +#endif /* IIO_DAC_DS4424_H_ */
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
kfifo;
> + }
> +
> + ret = dln2_register_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV,
> + dln2_adc_event);
> + if (ret) {
> + dev_err(dev, "failed to register event cb: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(dev, "failed to register iio device: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + return 0;
> +
> +dealloc_pollfunc:
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +dealloc_kfifo:
> +dealloc_trigger:
> + iio_trigger_unregister(dln2->trig);
> +dealloc_dev:
> +
> + return ret;
> +}
> +
> +static int dln2_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct dln2_adc *dln2 = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> + dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
> + iio_trigger_unregister(dln2->trig);
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +
> + return 0;
> +}
> +
> +static struct platform_driver dln2_adc_driver = {
> + .driver.name= DLN2_ADC_MOD_NAME,
> + .probe = dln2_adc_probe,
> + .remove = dln2_adc_remove,
> +};
> +
> +module_platform_driver(dln2_adc_driver);
> +
> +MODULE_AUTHOR("Jack Andersen <jackoa...@gmail.com");
> +MODULE_DESCRIPTION("Driver for the Diolan DLN2 ADC interface");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:dln2-adc");
> diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
> index 704e189..a22ab8c 100644
> --- a/drivers/mfd/dln2.c
> +++ b/drivers/mfd/dln2.c
> @@ -53,6 +53,7 @@ enum dln2_handle {
> DLN2_HANDLE_GPIO,
> DLN2_HANDLE_I2C,
> DLN2_HANDLE_SPI,
> + DLN2_HANDLE_ADC,
> DLN2_HANDLES
> };
>
> @@ -663,6 +664,12 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .port = 0,
> };
>
> +/* Only one ADC port supported */
> +static struct dln2_platform_data dln2_pdata_adc = {
> + .handle = DLN2_HANDLE_ADC,
> + .port = 0,
> +};
> +
> static const struct mfd_cell dln2_devs[] = {
> {
> .name = "dln2-gpio",
> @@ -679,6 +686,11 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .platform_data = _pdata_spi,
> .pdata_size = sizeof(struct dln2_platform_data),
> },
> + {
> + .name = "dln2-adc",
> + .platform_data = _pdata_adc,
> + .pdata_size = sizeof(struct dln2_platform_data),
> + },
> };
>
> static void dln2_stop(struct dln2_dev *dln2)
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
ret = dln2_register_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV,
> + dln2_adc_event);
> + if (ret) {
> + dev_err(dev, "failed to register event cb: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(dev, "failed to register iio device: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + return 0;
> +
> +dealloc_pollfunc:
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +dealloc_kfifo:
> +dealloc_trigger:
> + iio_trigger_unregister(dln2->trig);
> +dealloc_dev:
> +
> + return ret;
> +}
> +
> +static int dln2_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct dln2_adc *dln2 = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> + dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
> + iio_trigger_unregister(dln2->trig);
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +
> + return 0;
> +}
> +
> +static struct platform_driver dln2_adc_driver = {
> + .driver.name= DLN2_ADC_MOD_NAME,
> + .probe = dln2_adc_probe,
> + .remove = dln2_adc_remove,
> +};
> +
> +module_platform_driver(dln2_adc_driver);
> +
> +MODULE_AUTHOR("Jack Andersen +MODULE_DESCRIPTION("Driver for the Diolan DLN2 ADC interface");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:dln2-adc");
> diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
> index 704e189..a22ab8c 100644
> --- a/drivers/mfd/dln2.c
> +++ b/drivers/mfd/dln2.c
> @@ -53,6 +53,7 @@ enum dln2_handle {
> DLN2_HANDLE_GPIO,
> DLN2_HANDLE_I2C,
> DLN2_HANDLE_SPI,
> + DLN2_HANDLE_ADC,
> DLN2_HANDLES
> };
>
> @@ -663,6 +664,12 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .port = 0,
> };
>
> +/* Only one ADC port supported */
> +static struct dln2_platform_data dln2_pdata_adc = {
> + .handle = DLN2_HANDLE_ADC,
> + .port = 0,
> +};
> +
> static const struct mfd_cell dln2_devs[] = {
> {
> .name = "dln2-gpio",
> @@ -679,6 +686,11 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .platform_data = _pdata_spi,
> .pdata_size = sizeof(struct dln2_platform_data),
> },
> + {
> + .name = "dln2-adc",
> + .platform_data = _pdata_adc,
> + .pdata_size = sizeof(struct dln2_platform_data),
> + },
> };
>
> static void dln2_stop(struct dln2_dev *dln2)
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
dev_err(dev, "failed to register event cb: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(dev, "failed to register iio device: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + dev_info(dev, "DLN2 ADC driver loaded\n");
avoid this kind of logging
> +
> + return 0;
> +
> +dealloc_pollfunc:
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +dealloc_kfifo:
> +dealloc_trigger:
> + iio_trigger_unregister(dln2->trig);
> +dealloc_dev:
> +
> + return ret;
> +}
> +
> +static int dln2_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct dln2_adc *dln2 = iio_priv(indio_dev);
> +
> + dev_info(_dev->dev, "DLN2 ADC driver unloaded\n");
no such logging please
> +
> + dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
should be after device_unregister
> + iio_device_unregister(indio_dev);
> + iio_trigger_unregister(dln2->trig);
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +
> + return 0;
> +}
> +
> +static struct platform_driver dln2_adc_driver = {
> + .driver.name= DLN2_ADC_MOD_NAME,
> + .probe = dln2_adc_probe,
> + .remove = dln2_adc_remove,
> +};
> +
> +module_platform_driver(dln2_adc_driver);
> +
> +MODULE_AUTHOR("Jack Andersen <jackoa...@gmail.com");
> +MODULE_DESCRIPTION("Driver for the Diolan DLN2 ADC interface");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:dln2-adc");
> diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
> index 704e189..a22ab8c 100644
> --- a/drivers/mfd/dln2.c
> +++ b/drivers/mfd/dln2.c
> @@ -53,6 +53,7 @@ enum dln2_handle {
> DLN2_HANDLE_GPIO,
> DLN2_HANDLE_I2C,
> DLN2_HANDLE_SPI,
> + DLN2_HANDLE_ADC,
> DLN2_HANDLES
> };
>
> @@ -663,6 +664,12 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .port = 0,
> };
>
> +/* Only one ADC port supported */
> +static struct dln2_platform_data dln2_pdata_adc = {
> + .handle = DLN2_HANDLE_ADC,
> + .port = 0,
> +};
> +
> static const struct mfd_cell dln2_devs[] = {
> {
> .name = "dln2-gpio",
> @@ -679,6 +686,11 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .platform_data = _pdata_spi,
> .pdata_size = sizeof(struct dln2_platform_data),
> },
> + {
> + .name = "dln2-adc",
> + .platform_data = _pdata_adc,
> + .pdata_size = sizeof(struct dln2_platform_data),
> + },
> };
>
> static void dln2_stop(struct dln2_dev *dln2)
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
quot;failed to register event cb: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + ret = iio_device_register(indio_dev);
> + if (ret) {
> + dev_err(dev, "failed to register iio device: %d\n", ret);
> + goto dealloc_pollfunc;
> + }
> +
> + dev_info(dev, "DLN2 ADC driver loaded\n");
avoid this kind of logging
> +
> + return 0;
> +
> +dealloc_pollfunc:
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +dealloc_kfifo:
> +dealloc_trigger:
> + iio_trigger_unregister(dln2->trig);
> +dealloc_dev:
> +
> + return ret;
> +}
> +
> +static int dln2_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct dln2_adc *dln2 = iio_priv(indio_dev);
> +
> + dev_info(_dev->dev, "DLN2 ADC driver unloaded\n");
no such logging please
> +
> + dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV);
should be after device_unregister
> + iio_device_unregister(indio_dev);
> + iio_trigger_unregister(dln2->trig);
> + iio_dealloc_pollfunc(indio_dev->pollfunc);
> +
> + return 0;
> +}
> +
> +static struct platform_driver dln2_adc_driver = {
> + .driver.name= DLN2_ADC_MOD_NAME,
> + .probe = dln2_adc_probe,
> + .remove = dln2_adc_remove,
> +};
> +
> +module_platform_driver(dln2_adc_driver);
> +
> +MODULE_AUTHOR("Jack Andersen +MODULE_DESCRIPTION("Driver for the Diolan DLN2 ADC interface");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:dln2-adc");
> diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
> index 704e189..a22ab8c 100644
> --- a/drivers/mfd/dln2.c
> +++ b/drivers/mfd/dln2.c
> @@ -53,6 +53,7 @@ enum dln2_handle {
> DLN2_HANDLE_GPIO,
> DLN2_HANDLE_I2C,
> DLN2_HANDLE_SPI,
> + DLN2_HANDLE_ADC,
> DLN2_HANDLES
> };
>
> @@ -663,6 +664,12 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .port = 0,
> };
>
> +/* Only one ADC port supported */
> +static struct dln2_platform_data dln2_pdata_adc = {
> + .handle = DLN2_HANDLE_ADC,
> + .port = 0,
> +};
> +
> static const struct mfd_cell dln2_devs[] = {
> {
> .name = "dln2-gpio",
> @@ -679,6 +686,11 @@ static int dln2_start_rx_urbs(struct dln2_dev *dln2,
> gfp_t gfp)
> .platform_data = _pdata_spi,
> .pdata_size = sizeof(struct dln2_platform_data),
> },
> + {
> + .name = "dln2-adc",
> + .platform_data = _pdata_adc,
> + .pdata_size = sizeof(struct dln2_platform_data),
> + },
> };
>
> static void dln2_stop(struct dln2_dev *dln2)
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
Commit-ID: d15bc69affc57d7985a01745ca28eafa0772325b
Gitweb: http://git.kernel.org/tip/d15bc69affc57d7985a01745ca28eafa0772325b
Author: Peter Meerwald-Stadler <pme...@pmeerw.net>
AuthorDate: Tue, 30 May 2017 21:41:03 +0200
Committer: Thomas Gleixner <t...@linutronix.de>
Com
Commit-ID: d15bc69affc57d7985a01745ca28eafa0772325b
Gitweb: http://git.kernel.org/tip/d15bc69affc57d7985a01745ca28eafa0772325b
Author: Peter Meerwald-Stadler
AuthorDate: Tue, 30 May 2017 21:41:03 +0200
Committer: Thomas Gleixner
CommitDate: Tue, 20 Jun 2017 21:33:55 +0200
timers: Fix
Signed-off-by: Peter Meerwald-Stadler <pme...@pmeerw.net>
Cc: John Stultz <john.stu...@linaro.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: triv...@rustcorp.com.au
---
kernel/time/timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/time/tim
Signed-off-by: Peter Meerwald-Stadler
Cc: John Stultz
Cc: Thomas Gleixner
Cc: triv...@rustcorp.com.au
---
kernel/time/timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 152a706ef8b8..709a404bd133 100644
--- a/kernel/time
> - if (ret != -ERESTARTSYS)
> - zpa2326_warn(indio_dev, "no one shot interrupt occurred (%d)",
> - ret);
> + } else if (timeout < 0) {
> + zpa2326_warn(indio_dev, "wait for one shot interrupt canceled");
> + ret = -ERESTARTSYS;
> + }
>
> return ret;
> }
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
TSYS)
> - zpa2326_warn(indio_dev, "no one shot interrupt occurred (%d)",
> - ret);
> + } else if (timeout < 0) {
> + zpa2326_warn(indio_dev, "wait for one shot interrupt canceled");
> + ret = -ERESTARTSYS;
> + }
>
> return ret;
> }
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
; + /* Turn on temperature measurement in the background */
> + r = regmap_write_bits(data->regmap, MEAS_CFG, MEAS_CTRL_BITS,
> + TEMP_EN | BACKGROUND);
should be disabled again if _probe fails lateron
> + if (r < 0)
> + return r;
> +
> + /*
> + * Calibration coefficients required for reporting temperature.
> + * They are availalbe 40ms after the device has started
available
> + */
> + r = dps310_get_temp_coef(data);
> + if (r == -EAGAIN)
> + return -EPROBE_DEFER;
wouldn't it make more sense to wait for the data to become ready, maybe
with a timeout?
> + if (r < 0)
> + return r;
> +
> + r = devm_iio_device_register(>dev, iio);
> + if (r)
> + return r;
> +
> + i2c_set_clientdata(client, iio);
> +
> + dev_info(>dev, "%s: sensor '%s'\n", dev_name(>dev),
> + client->name);
no extra logging, this adds little extra information
> + return 0;
> +}
turn off measurement in _remove()?
> +
> +static const struct i2c_device_id dps310_id[] = {
> + { "dps310", 0 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, dps310_id);
> +
> +static const unsigned short normal_i2c[] = {
> + 0x77, 0x76, I2C_CLIENT_END
> +};
> +
> +static struct i2c_driver dps310_driver = {
> + .driver = {
> + .name = "dps310",
> + },
> + .probe = dps310_probe,
> + .address_list = normal_i2c,
> + .id_table = dps310_id,
> +};
> +module_i2c_driver(dps310_driver);
> +
> +MODULE_AUTHOR("Joel Stanley <j...@jms.id.au>");
> +MODULE_DESCRIPTION("Infineon DPS310 pressure and temperature sensor");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
n the background */
> + r = regmap_write_bits(data->regmap, MEAS_CFG, MEAS_CTRL_BITS,
> + TEMP_EN | BACKGROUND);
should be disabled again if _probe fails lateron
> + if (r < 0)
> + return r;
> +
> + /*
> + * Calibration coefficients required for reporting temperature.
> + * They are availalbe 40ms after the device has started
available
> + */
> + r = dps310_get_temp_coef(data);
> + if (r == -EAGAIN)
> + return -EPROBE_DEFER;
wouldn't it make more sense to wait for the data to become ready, maybe
with a timeout?
> + if (r < 0)
> + return r;
> +
> + r = devm_iio_device_register(>dev, iio);
> + if (r)
> + return r;
> +
> + i2c_set_clientdata(client, iio);
> +
> + dev_info(>dev, "%s: sensor '%s'\n", dev_name(>dev),
> + client->name);
no extra logging, this adds little extra information
> + return 0;
> +}
turn off measurement in _remove()?
> +
> +static const struct i2c_device_id dps310_id[] = {
> + { "dps310", 0 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, dps310_id);
> +
> +static const unsigned short normal_i2c[] = {
> + 0x77, 0x76, I2C_CLIENT_END
> +};
> +
> +static struct i2c_driver dps310_driver = {
> + .driver = {
> + .name = "dps310",
> + },
> + .probe = dps310_probe,
> + .address_list = normal_i2c,
> + .id_table = dps310_id,
> +};
> +module_i2c_driver(dps310_driver);
> +
> +MODULE_AUTHOR("Joel Stanley ");
> +MODULE_DESCRIPTION("Infineon DPS310 pressure and temperature sensor");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> struct zpa2326_private *private,
> int irq)
> {
> int err;
>
> private->irq = irq;
>
> if (irq <= 0) {
> /*
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> struct zpa2326_private *private,
> int irq)
> {
> int err;
>
> private->irq = irq;
>
> if (irq <= 0) {
> /*
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
1x8s102_id[] = {
> + { "adc1x8s102", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(spi, adc1x8s102_id);
> +
> +static struct spi_driver adc1x8s102_driver = {
> + .driver = {
> + .name = "adc1x8s102",
> + .owner = THIS_MODULE,
> + .acpi_match_table = ACPI_PTR(adc1x8s102_acpi_ids),
> + },
> + .probe = adc1x8s102_probe,
> + .remove = adc1x8s102_remove,
> + .id_table = adc1x8s102_id,
> +};
> +module_spi_driver(adc1x8s102_driver);
> +
> +MODULE_AUTHOR("Bogdan Pricop <bogdan.pri...@emutex.com>");
> +MODULE_DESCRIPTION("Texas Instruments ADC1x8S102 driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/platform_data/adc1x8s102.h
> b/include/linux/platform_data/adc1x8s102.h
> new file mode 100644
> index ..6ad753c99823
> --- /dev/null
> +++ b/include/linux/platform_data/adc1x8s102.h
> @@ -0,0 +1,28 @@
> +/*
> + * ADC1x8S102 SPI ADC driver
> + *
> + * Copyright(c) 2013 Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + */
> +
> +#ifndef __LINUX_PLATFORM_DATA_ADC1x8S102_H__
> +#define __LINUX_PLATFORM_DATA_ADC1x8S102_H__
> +
> +/**
> + * struct adc1x8s102_platform_data - Platform data for the adc1x8s102 ADC
> driver
> + * @ext_vin: External input voltage range for all voltage input channels
> + * This is the voltage level of pin VA in millivolts
> + **/
> +struct adc1x8s102_platform_data {
> + u16 ext_vin;
> +};
> +
> +#endif /* __LINUX_PLATFORM_DATA_ADC1x8S102_H__ */
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
LE_DEVICE_TABLE(spi, adc1x8s102_id);
> +
> +static struct spi_driver adc1x8s102_driver = {
> + .driver = {
> + .name = "adc1x8s102",
> + .owner = THIS_MODULE,
> + .acpi_match_table = ACPI_PTR(adc1x8s102_acpi_ids),
> + },
> + .probe = adc1x8s102_probe,
> + .remove = adc1x8s102_remove,
> + .id_table = adc1x8s102_id,
> +};
> +module_spi_driver(adc1x8s102_driver);
> +
> +MODULE_AUTHOR("Bogdan Pricop ");
> +MODULE_DESCRIPTION("Texas Instruments ADC1x8S102 driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/platform_data/adc1x8s102.h
> b/include/linux/platform_data/adc1x8s102.h
> new file mode 100644
> index ..6ad753c99823
> --- /dev/null
> +++ b/include/linux/platform_data/adc1x8s102.h
> @@ -0,0 +1,28 @@
> +/*
> + * ADC1x8S102 SPI ADC driver
> + *
> + * Copyright(c) 2013 Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + */
> +
> +#ifndef __LINUX_PLATFORM_DATA_ADC1x8S102_H__
> +#define __LINUX_PLATFORM_DATA_ADC1x8S102_H__
> +
> +/**
> + * struct adc1x8s102_platform_data - Platform data for the adc1x8s102 ADC
> driver
> + * @ext_vin: External input voltage range for all voltage input channels
> + * This is the voltage level of pin VA in millivolts
> + **/
> +struct adc1x8s102_platform_data {
> + u16 ext_vin;
> +};
> +
> +#endif /* __LINUX_PLATFORM_DATA_ADC1x8S102_H__ */
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
}
> +
> + for (i = 0; i < ARRAY_SIZE(stm32_dac_channels); i++) {
> + if (stm32_dac_channels[i].channel == channel)
> + break;
> + }
> + if (i >= ARRAY_SIZE(stm32_dac_channels)) {
> + dev_err(_dev->dev, "Invalid st,dac-channel\n"
> + if (i >= ARRAY_SIZE(stm32_dac_channels)) {
> + dev_err(_dev->dev, "Invalid st,dac-channel\n");
> + return -EINVAL;
> + }
> +
> + indio_dev->channels = _dac_channels[i];
> + indio_dev->num_channels = 1;
this is unusual, a comment would be helpful
why not expose both channels?
> +
> + return 0;
> +};
> +
> +static int stm32_dac_probe(struct platform_device *pdev)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + struct iio_dev *indio_dev;
> + struct stm32_dac *dac;
> + int ret;
> +
> + if (!np)
> + return -ENODEV;
> +
> + indio_dev = devm_iio_device_alloc(>dev, sizeof(*dac));
> + if (!indio_dev)
> + return -ENOMEM;
> + platform_set_drvdata(pdev, indio_dev);
> +
> + dac = iio_priv(indio_dev);
> + dac->common = dev_get_drvdata(pdev->dev.parent);
> + indio_dev->name = dev_name(>dev);
> + indio_dev->dev.parent = >dev;
> + indio_dev->dev.of_node = pdev->dev.of_node;
> + indio_dev->info = _dac_iio_info;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> +
> + ret = stm32_dac_chan_of_init(indio_dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
just
return iio_device_register();
candidate for devm_ due to empty _remove()
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int stm32_dac_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> + iio_device_unregister(indio_dev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id stm32_dac_of_match[] = {
> + { .compatible = "st,stm32-dac", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, stm32_dac_of_match);
> +
> +static struct platform_driver stm32_dac_driver = {
> + .probe = stm32_dac_probe,
> + .remove = stm32_dac_remove,
> + .driver = {
> + .name = "stm32-dac",
> + .of_match_table = stm32_dac_of_match,
> + },
> +};
> +module_platform_driver(stm32_dac_driver);
> +
> +MODULE_ALIAS("platform:stm32-dac");
> +MODULE_AUTHOR("Amelie Delaunay ");
> +MODULE_DESCRIPTION("STMicroelectronics STM32 DAC driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
des = INDIO_DIRECT_MODE;
> > - indio_dev->channels = max11100_channels,
> > - indio_dev->num_channels = ARRAY_SIZE(max11100_channels),
> > + indio_dev->channels = max11100_channels;
> > + indio_dev->num_channels = ARRAY_SIZE(max11100_channels);
> >
> > state->vref_reg = devm_regulator_get(>dev, "vref");
> > if (IS_ERR(state->vref_reg))
> > --
> > 2.11.0
> >
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
indio_dev->channels = max11100_channels,
> > - indio_dev->num_channels = ARRAY_SIZE(max11100_channels),
> > + indio_dev->channels = max11100_channels;
> > + indio_dev->num_channels = ARRAY_SIZE(max11100_channels);
> >
> > state->vref_reg = devm_regulator_get(>dev, "vref");
> > if (IS_ERR(state->vref_reg))
> > --
> > 2.11.0
> >
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
ev, indio_dev);
no devm_ since we have a non-empty _remove()?
> + if (ret < 0)
> + goto err_regulator_disable;
> +
> + return 0;
> +
> +err_regulator_disable:
> + regulator_disable(st->ref);
> +
> + return ret;
> +}
> +
> +static int ltc2497_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct ltc2497_st *st = iio_priv(indio_dev);
> +
> + regulator_disable(st->ref);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id ltc2497_id[] = {
> + { "ltc2497", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, ltc2497_id);
> +
> +static const struct of_device_id ltc2497_of_match[] = {
> + { .compatible = "lltc,ltc2497", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, ltc2497_of_match);
> +
> +static struct i2c_driver ltc2497_driver = {
> + .driver = {
> + .name = "ltc2497",
> + .of_match_table = of_match_ptr(ltc2497_of_match),
> + },
> + .probe = ltc2497_probe,
> + .remove = ltc2497_remove,
> + .id_table = ltc2497_id,
> +};
> +module_i2c_driver(ltc2497_driver);
> +
> +MODULE_AUTHOR("Michael Hennerich <michael.henner...@analog.com>");
> +MODULE_DESCRIPTION("Linear Technology LTC2497 ADC driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
ret < 0)
> + goto err_regulator_disable;
> +
> + return 0;
> +
> +err_regulator_disable:
> + regulator_disable(st->ref);
> +
> + return ret;
> +}
> +
> +static int ltc2497_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct ltc2497_st *st = iio_priv(indio_dev);
> +
> + regulator_disable(st->ref);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id ltc2497_id[] = {
> + { "ltc2497", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, ltc2497_id);
> +
> +static const struct of_device_id ltc2497_of_match[] = {
> + { .compatible = "lltc,ltc2497", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, ltc2497_of_match);
> +
> +static struct i2c_driver ltc2497_driver = {
> + .driver = {
> + .name = "ltc2497",
> + .of_match_table = of_match_ptr(ltc2497_of_match),
> + },
> + .probe = ltc2497_probe,
> + .remove = ltc2497_remove,
> + .id_table = ltc2497_id,
> +};
> +module_i2c_driver(ltc2497_driver);
> +
> +MODULE_AUTHOR("Michael Hennerich ");
> +MODULE_DESCRIPTION("Linear Technology LTC2497 ADC driver");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
w_unregister_divider(data->clk_prescaler);
> +
> +prescaler_error:
> +resource_error:
> + return ret;
> +}
> +
> +static int aspeed_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct aspeed_adc_data *data = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
writel(0x0, data->base + ASPEED_ADC_REG_ENGINE_CONTROL);
I guess this power off the device?
the MODE #defines are now used (powerdown, normal, etc.)
> + clk_disable_unprepare(data->clk_scaler->clk);
> + clk_hw_unregister_divider(data->clk_scaler);
> + clk_hw_unregister_divider(data->clk_prescaler);
> +
> + return 0;
> +}
> +
> +const struct of_device_id aspeed_adc_matches[] = {
> + { .compatible = "aspeed,ast2400-adc" },
> + { .compatible = "aspeed,ast2500-adc" },
> +};
> +MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
> +
> +static struct platform_driver aspeed_adc_driver = {
> + .probe = aspeed_adc_probe,
> + .remove = aspeed_adc_remove,
> + .driver = {
> + .name = KBUILD_MODNAME,
> + .of_match_table = aspeed_adc_matches,
> + }
> +};
> +
> +module_platform_driver(aspeed_adc_driver);
> +
> +MODULE_AUTHOR("Rick Altherr <ralth...@google.com>");
> +MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
> +prescaler_error:
> +resource_error:
> + return ret;
> +}
> +
> +static int aspeed_adc_remove(struct platform_device *pdev)
> +{
> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> + struct aspeed_adc_data *data = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
writel(0x0, data->base + ASPEED_ADC_REG_ENGINE_CONTROL);
I guess this power off the device?
the MODE #defines are now used (powerdown, normal, etc.)
> + clk_disable_unprepare(data->clk_scaler->clk);
> + clk_hw_unregister_divider(data->clk_scaler);
> + clk_hw_unregister_divider(data->clk_prescaler);
> +
> + return 0;
> +}
> +
> +const struct of_device_id aspeed_adc_matches[] = {
> + { .compatible = "aspeed,ast2400-adc" },
> + { .compatible = "aspeed,ast2500-adc" },
> +};
> +MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
> +
> +static struct platform_driver aspeed_adc_driver = {
> + .probe = aspeed_adc_probe,
> + .remove = aspeed_adc_remove,
> + .driver = {
> + .name = KBUILD_MODNAME,
> + .of_match_table = aspeed_adc_matches,
> + }
> +};
> +
> +module_platform_driver(aspeed_adc_driver);
> +
> +MODULE_AUTHOR("Rick Altherr ");
> +MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver");
> +MODULE_LICENSE("GPL");
>
--
Peter Meerwald-Stadler
Mobile: +43 664 24 44 418
_dev)
> + return -ENOMEM;
> +
> + data = iio_priv(indio_dev);
> + i2c_set_clientdata(client, indio_dev);
> + data->client = client;
> + mutex_init(>lock);
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->name = id->name;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> + indio_dev->channels = sht21_channels;
> + indio_dev->num_channels = ARRAY_SIZE(sht21_channels);
> +
> + ret = sht21_soft_reset(data);
> + if (ret)
> + return ret;
> +
> + ret = iio_triggered_buffer_setup(indio_dev, NULL,
> + sht21_trigger_handler, NULL);
> + if (ret)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret)
> + iio_triggered_buffer_cleanup(indio_dev);
> +
> + return ret;
> +}
> +
> +static int sht21_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> + iio_triggered_buffer_cleanup(indio_dev);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id sht21_id[] = {
> + { "sht21", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, sht21_id);
> +
> +static const struct of_device_id sht21_of_match[] = {
> + { .compatible = "sensirion,sht21" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, sht21_of_match);
> +
> +static struct i2c_driver sht21_driver = {
> + .driver = {
> + .name = SHT21_DRV_NAME,
> + .of_match_table = of_match_ptr(sht21_of_match),
> + },
> + .id_table = sht21_id,
> + .probe = sht21_probe,
> + .remove = sht21_remove,
> +};
> +module_i2c_driver(sht21_driver);
> +
> +MODULE_DESCRIPTION("Sensirion SHT21 relative humidity and temperature sensor
> driver");
> +MODULE_AUTHOR("Tomasz Duszynski <tdusz...@gmail.com>");
> +MODULE_LICENSE("GPL v2");
> --
> 2.11.1
>
--
Peter Meerwald-Stadler
+43-664-218 (mobile)
ata = iio_priv(indio_dev);
> + i2c_set_clientdata(client, indio_dev);
> + data->client = client;
> + mutex_init(>lock);
> +
> + indio_dev->dev.parent = >dev;
> + indio_dev->name = id->name;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = _info;
> + indio_dev->channels = sht21_channels;
> + indio_dev->num_channels = ARRAY_SIZE(sht21_channels);
> +
> + ret = sht21_soft_reset(data);
> + if (ret)
> + return ret;
> +
> + ret = iio_triggered_buffer_setup(indio_dev, NULL,
> + sht21_trigger_handler, NULL);
> + if (ret)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret)
> + iio_triggered_buffer_cleanup(indio_dev);
> +
> + return ret;
> +}
> +
> +static int sht21_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> + iio_triggered_buffer_cleanup(indio_dev);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id sht21_id[] = {
> + { "sht21", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, sht21_id);
> +
> +static const struct of_device_id sht21_of_match[] = {
> + { .compatible = "sensirion,sht21" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, sht21_of_match);
> +
> +static struct i2c_driver sht21_driver = {
> + .driver = {
> + .name = SHT21_DRV_NAME,
> + .of_match_table = of_match_ptr(sht21_of_match),
> + },
> + .id_table = sht21_id,
> + .probe = sht21_probe,
> + .remove = sht21_remove,
> +};
> +module_i2c_driver(sht21_driver);
> +
> +MODULE_DESCRIPTION("Sensirion SHT21 relative humidity and temperature sensor
> driver");
> +MODULE_AUTHOR("Tomasz Duszynski ");
> +MODULE_LICENSE("GPL v2");
> --
> 2.11.1
>
--
Peter Meerwald-Stadler
+43-664-218 (mobile)
/types.h
> @@ -43,6 +43,7 @@ enum iio_chan_type {
> IIO_COUNT,
> IIO_INDEX,
> IIO_GRAVITY,
> + IIO_NUMBERCONCENTRATION,
> };
>
> enum iio_modifier {
>
--
Peter Meerwald-Stadler
+43-664-218 (mobile)
};
>
> static const char * const iio_modifier_names[] = {
> diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
> index ffafd6c25a48..52696e251c4d 100644
> --- a/include/uapi/linux/iio/types.h
> +++ b/include/uapi/linux/iio/types.h
> @@ -43,6 +43,7 @@ enum iio
1 - 100 of 460 matches
Mail list logo