From ddeb64f36d2a1333927e273856d545767ee70a1c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Sat, 1 Jun 2013 08:10:00 +0100 Subject: [PATCH 01/15] iio: replace strict_strtoul() with kstrtoul() The usage of strict_strtoul() is not preferred, because strict_strtoul() is obsolete. Thus, kstrtoul() should be used. Signed-off-by: Jingoo Han Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1363.c | 2 +- drivers/iio/trigger/iio-trig-sysfs.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 9e6da72ad823..f148d00b83f7 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -660,7 +660,7 @@ static ssize_t max1363_monitor_store_freq(struct device *dev, unsigned long val; bool found = false; - ret = strict_strtoul(buf, 10, &val); + ret = kstrtoul(buf, 10, &val); if (ret) return -EINVAL; for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++) diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c index b727bde8b7fe..effcd0ac98d8 100644 --- a/drivers/iio/trigger/iio-trig-sysfs.c +++ b/drivers/iio/trigger/iio-trig-sysfs.c @@ -34,7 +34,7 @@ static ssize_t iio_sysfs_trig_add(struct device *dev, int ret; unsigned long input; - ret = strict_strtoul(buf, 10, &input); + ret = kstrtoul(buf, 10, &input); if (ret) return ret; ret = iio_sysfs_trigger_probe(input); @@ -53,7 +53,7 @@ static ssize_t iio_sysfs_trig_remove(struct device *dev, int ret; unsigned long input; - ret = strict_strtoul(buf, 10, &input); + ret = kstrtoul(buf, 10, &input); if (ret) return ret; ret = iio_sysfs_trigger_remove(input); From 00738ff6660c74816300ccca3f3d29ffe24ae733 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 23 May 2013 06:26:00 +0100 Subject: [PATCH 02/15] iio: at91_adc: Add missing CONFIG_OF macro The data structure is required only when DT is enabled. Hence compile it conditionally. Signed-off-by: Sachin Kamat Acked-by: Maxime Ripard Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index e5b88d5d3b59..b6db6a0e09cd 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -774,11 +774,13 @@ static int at91_adc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF static const struct of_device_id at91_adc_dt_ids[] = { { .compatible = "atmel,at91sam9260-adc" }, {}, }; MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); +#endif static struct platform_driver at91_adc_driver = { .probe = at91_adc_probe, From b840333e955eff9a8db33af1e1ff409ca4e55502 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Jun 2013 20:00:00 +0100 Subject: [PATCH 03/15] staging:iio:trigger:gpio bug in release of gpio in error path Also dropped the unneeded gpio.h header. Signed-off-by: Jonathan Cameron Reviewed-by: Lars-Peter Clausen --- drivers/staging/iio/trigger/iio-trig-gpio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index 7c593d18a910..69dabca0f4e8 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -122,7 +121,7 @@ error_free_completed_registrations: &iio_gpio_trigger_list, alloc_list) { trig_info = iio_trigger_get_drvdata(trig); - free_irq(gpio_to_irq(trig_info->irq), trig); + free_irq(trig_info->irq, trig); kfree(trig_info); iio_trigger_unregister(trig); } From d4fd73bf25c3aafc891ef4443fc744d427ec1df0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Jun 2013 20:00:00 +0100 Subject: [PATCH 04/15] staging:iio:triggers: rename iio-trig-gpio to iio-trig-interrupt Also change all internal naming appropriately. This trigger is no longer just for gpio provided interrupts so change the naming to reflect this. Also drop some now missleading left over comments. Signed-off-by: Jonathan Cameron Reviewed-by: Lars-Peter Clausen --- drivers/staging/iio/trigger/Kconfig | 8 +-- drivers/staging/iio/trigger/Makefile | 2 +- .../{iio-trig-gpio.c => iio-trig-interrupt.c} | 66 ++++++++----------- 3 files changed, 31 insertions(+), 45 deletions(-) rename drivers/staging/iio/trigger/{iio-trig-gpio.c => iio-trig-interrupt.c} (60%) diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index ae9fcd3382ea..4ecb213b861f 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -12,11 +12,11 @@ config IIO_PERIODIC_RTC_TRIGGER Provides support for using periodic capable real time clocks as IIO triggers. -config IIO_GPIO_TRIGGER - tristate "GPIO trigger" - depends on GPIOLIB +config IIO_INTERRUPT_TRIGGER + tristate "Generic interrupt trigger" help - Provides support for using GPIO pins as IIO triggers. + Provides support for using interrupts of various types as IIO + triggers. These may be provided by a gpio driver for example. config IIO_BFIN_TMR_TRIGGER tristate "Blackfin TIMER trigger" diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile index 8a5304153b5b..48f2236147bb 100644 --- a/drivers/staging/iio/trigger/Makefile +++ b/drivers/staging/iio/trigger/Makefile @@ -3,5 +3,5 @@ # obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o -obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o +obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-interrupt.c similarity index 60% rename from drivers/staging/iio/trigger/iio-trig-gpio.c rename to drivers/staging/iio/trigger/iio-trig-interrupt.c index 69dabca0f4e8..9afba960e419 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-interrupt.c @@ -1,18 +1,11 @@ /* - * Industrial I/O - gpio based trigger support + * Industrial I/O - generic interrupt based trigger support * - * Copyright (c) 2008 Jonathan Cameron + * Copyright (c) 2008-2013 Jonathan Cameron * * 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. - * - * Currently this is more of a functioning proof of concept than a full - * fledged trigger driver. - * - * TODO: - * - * Add board config elements to allow specification of startup settings. */ #include @@ -24,35 +17,28 @@ #include #include -static LIST_HEAD(iio_gpio_trigger_list); -static DEFINE_MUTEX(iio_gpio_trigger_list_lock); +static LIST_HEAD(iio_interrupt_trigger_list); +static DEFINE_MUTEX(iio_interrupt_trigger_list_lock); -struct iio_gpio_trigger_info { +struct iio_interrupt_trigger_info { struct mutex in_use; unsigned int irq; }; -/* - * Need to reference count these triggers and only enable gpio interrupts - * as appropriate. - */ -/* So what functionality do we want in here?... */ -/* set high / low as interrupt type? */ - -static irqreturn_t iio_gpio_trigger_poll(int irq, void *private) +static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private) { /* Timestamp not currently provided */ iio_trigger_poll(private, 0); return IRQ_HANDLED; } -static const struct iio_trigger_ops iio_gpio_trigger_ops = { +static const struct iio_trigger_ops iio_interrupt_trigger_ops = { .owner = THIS_MODULE, }; -static int iio_gpio_trigger_probe(struct platform_device *pdev) +static int iio_interrupt_trigger_probe(struct platform_device *pdev) { - struct iio_gpio_trigger_info *trig_info; + struct iio_interrupt_trigger_info *trig_info; struct iio_trigger *trig, *trig2; unsigned long irqflags; struct resource *irq_res; @@ -64,7 +50,7 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) if (irq_res == NULL) { if (irq_res_cnt == 0) - dev_err(&pdev->dev, "No GPIO IRQs specified"); + dev_err(&pdev->dev, "No IRQs specified"); break; } irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; @@ -84,8 +70,8 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) } iio_trigger_set_drvdata(trig, trig_info); trig_info->irq = irq; - trig->ops = &iio_gpio_trigger_ops; - ret = request_irq(irq, iio_gpio_trigger_poll, + trig->ops = &iio_interrupt_trigger_ops; + ret = request_irq(irq, iio_interrupt_trigger_poll, irqflags, trig->name, trig); if (ret) { dev_err(&pdev->dev, @@ -98,7 +84,7 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) goto error_release_irq; list_add_tail(&trig->alloc_list, - &iio_gpio_trigger_list); + &iio_interrupt_trigger_list); } irq_res_cnt++; @@ -115,10 +101,10 @@ error_free_trig_info: error_put_trigger: iio_trigger_put(trig); error_free_completed_registrations: - /* The rest should have been added to the iio_gpio_trigger_list */ + /* The rest should have been added to the iio_interrupt_trigger_list */ list_for_each_entry_safe(trig, trig2, - &iio_gpio_trigger_list, + &iio_interrupt_trigger_list, alloc_list) { trig_info = iio_trigger_get_drvdata(trig); free_irq(trig_info->irq, trig); @@ -129,15 +115,15 @@ error_free_completed_registrations: return ret; } -static int iio_gpio_trigger_remove(struct platform_device *pdev) +static int iio_interrupt_trigger_remove(struct platform_device *pdev) { struct iio_trigger *trig, *trig2; - struct iio_gpio_trigger_info *trig_info; + struct iio_interrupt_trigger_info *trig_info; - mutex_lock(&iio_gpio_trigger_list_lock); + mutex_lock(&iio_interrupt_trigger_list_lock); list_for_each_entry_safe(trig, trig2, - &iio_gpio_trigger_list, + &iio_interrupt_trigger_list, alloc_list) { trig_info = iio_trigger_get_drvdata(trig); iio_trigger_unregister(trig); @@ -145,22 +131,22 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev) kfree(trig_info); iio_trigger_put(trig); } - mutex_unlock(&iio_gpio_trigger_list_lock); + mutex_unlock(&iio_interrupt_trigger_list_lock); return 0; } -static struct platform_driver iio_gpio_trigger_driver = { - .probe = iio_gpio_trigger_probe, - .remove = iio_gpio_trigger_remove, +static struct platform_driver iio_interrupt_trigger_driver = { + .probe = iio_interrupt_trigger_probe, + .remove = iio_interrupt_trigger_remove, .driver = { - .name = "iio_gpio_trigger", + .name = "iio_interrupt_trigger", .owner = THIS_MODULE, }, }; -module_platform_driver(iio_gpio_trigger_driver); +module_platform_driver(iio_interrupt_trigger_driver); MODULE_AUTHOR("Jonathan Cameron "); -MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem"); +MODULE_DESCRIPTION("Interrupt trigger for the iio subsystem"); MODULE_LICENSE("GPL v2"); From 3c1e02dbb3843f5405279aeb0aaa515da2782f85 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Jun 2013 20:00:00 +0100 Subject: [PATCH 05/15] staging:iio:triggers:interrupt trigger - one per platform device. Switching from one platform device registering a lot of triggers to one for each trigger simplifies the code somewhat. It would be relatively unusual to have more than a couple of such devices registered so this change will not result in much additional overhead. Signed-off-by: Jonathan Cameron Reviewed-by: Lars-Peter Clausen --- .../staging/iio/trigger/iio-trig-interrupt.c | 109 +++++++----------- 1 file changed, 39 insertions(+), 70 deletions(-) diff --git a/drivers/staging/iio/trigger/iio-trig-interrupt.c b/drivers/staging/iio/trigger/iio-trig-interrupt.c index 9afba960e419..84bf397ec465 100644 --- a/drivers/staging/iio/trigger/iio-trig-interrupt.c +++ b/drivers/staging/iio/trigger/iio-trig-interrupt.c @@ -17,11 +17,8 @@ #include #include -static LIST_HEAD(iio_interrupt_trigger_list); -static DEFINE_MUTEX(iio_interrupt_trigger_list_lock); struct iio_interrupt_trigger_info { - struct mutex in_use; unsigned int irq; }; @@ -39,57 +36,46 @@ static const struct iio_trigger_ops iio_interrupt_trigger_ops = { static int iio_interrupt_trigger_probe(struct platform_device *pdev) { struct iio_interrupt_trigger_info *trig_info; - struct iio_trigger *trig, *trig2; + struct iio_trigger *trig; unsigned long irqflags; struct resource *irq_res; - int irq, ret = 0, irq_res_cnt = 0; + int irq, ret = 0; - do { - irq_res = platform_get_resource(pdev, - IORESOURCE_IRQ, irq_res_cnt); + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (irq_res == NULL) { - if (irq_res_cnt == 0) - dev_err(&pdev->dev, "No IRQs specified"); - break; - } - irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; + if (irq_res == NULL) + return -ENODEV; - for (irq = irq_res->start; irq <= irq_res->end; irq++) { + irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; - trig = iio_trigger_alloc("irqtrig%d", irq); - if (!trig) { - ret = -ENOMEM; - goto error_free_completed_registrations; - } + irq = irq_res->start; - trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); - if (!trig_info) { - ret = -ENOMEM; - goto error_put_trigger; - } - iio_trigger_set_drvdata(trig, trig_info); - trig_info->irq = irq; - trig->ops = &iio_interrupt_trigger_ops; - ret = request_irq(irq, iio_interrupt_trigger_poll, - irqflags, trig->name, trig); - if (ret) { - dev_err(&pdev->dev, - "request IRQ-%d failed", irq); - goto error_free_trig_info; - } + trig = iio_trigger_alloc("irqtrig%d", irq_res->start); + if (!trig) { + ret = -ENOMEM; + goto error_ret; + } - ret = iio_trigger_register(trig); - if (ret) - goto error_release_irq; - - list_add_tail(&trig->alloc_list, - &iio_interrupt_trigger_list); - } - - irq_res_cnt++; - } while (irq_res != NULL); + trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); + if (!trig_info) { + ret = -ENOMEM; + goto error_put_trigger; + } + iio_trigger_set_drvdata(trig, trig_info); + trig_info->irq = irq; + trig->ops = &iio_interrupt_trigger_ops; + ret = request_irq(irq, iio_interrupt_trigger_poll, + irqflags, trig->name, trig); + if (ret) { + dev_err(&pdev->dev, + "request IRQ-%d failed", irq); + goto error_free_trig_info; + } + ret = iio_trigger_register(trig); + if (ret) + goto error_release_irq; + platform_set_drvdata(pdev, trig); return 0; @@ -100,38 +86,21 @@ error_free_trig_info: kfree(trig_info); error_put_trigger: iio_trigger_put(trig); -error_free_completed_registrations: - /* The rest should have been added to the iio_interrupt_trigger_list */ - list_for_each_entry_safe(trig, - trig2, - &iio_interrupt_trigger_list, - alloc_list) { - trig_info = iio_trigger_get_drvdata(trig); - free_irq(trig_info->irq, trig); - kfree(trig_info); - iio_trigger_unregister(trig); - } - +error_ret: return ret; } static int iio_interrupt_trigger_remove(struct platform_device *pdev) { - struct iio_trigger *trig, *trig2; + struct iio_trigger *trig; struct iio_interrupt_trigger_info *trig_info; - mutex_lock(&iio_interrupt_trigger_list_lock); - list_for_each_entry_safe(trig, - trig2, - &iio_interrupt_trigger_list, - alloc_list) { - trig_info = iio_trigger_get_drvdata(trig); - iio_trigger_unregister(trig); - free_irq(trig_info->irq, trig); - kfree(trig_info); - iio_trigger_put(trig); - } - mutex_unlock(&iio_interrupt_trigger_list_lock); + trig = platform_get_drvdata(pdev); + trig_info = iio_trigger_get_drvdata(trig); + iio_trigger_unregister(trig); + free_irq(trig_info->irq, trig); + kfree(trig_info); + iio_trigger_put(trig); return 0; } From c7a8be08da50eb5e30eaa6555079c10b8e23521a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Jun 2013 20:00:00 +0100 Subject: [PATCH 06/15] iio:triggers:interrupt trigger - move out of staging. This is now a very simple trigger indeed but useful in many common cases. Signed-off-by: Jonathan Cameron Reviewed-by: Lars-Peter Clausen --- drivers/iio/trigger/Kconfig | 9 +++++++++ drivers/iio/trigger/Makefile | 1 + drivers/{staging => }/iio/trigger/iio-trig-interrupt.c | 0 drivers/staging/iio/trigger/Kconfig | 6 ------ drivers/staging/iio/trigger/Makefile | 1 - 5 files changed, 10 insertions(+), 7 deletions(-) rename drivers/{staging => }/iio/trigger/iio-trig-interrupt.c (100%) diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig index a4e68db2f23f..360fd508b088 100644 --- a/drivers/iio/trigger/Kconfig +++ b/drivers/iio/trigger/Kconfig @@ -3,6 +3,15 @@ # menu "Triggers - standalone" +config IIO_INTERRUPT_TRIGGER + tristate "Generic interrupt trigger" + help + Provides support for using an interrupt of any type as an IIO + trigger. This may be provided by a gpio driver for example. + + To compile this driver as a module, choose M here: the + module will be called iio-trig-interrupt. + config IIO_SYSFS_TRIGGER tristate "SYSFS trigger" depends on SYSFS diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile index e0b21831072f..ce319a51b6af 100644 --- a/drivers/iio/trigger/Makefile +++ b/drivers/iio/trigger/Makefile @@ -2,4 +2,5 @@ # Makefile for triggers not associated with iio-devices # +obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o diff --git a/drivers/staging/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c similarity index 100% rename from drivers/staging/iio/trigger/iio-trig-interrupt.c rename to drivers/iio/trigger/iio-trig-interrupt.c diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index 4ecb213b861f..2fd18c60323d 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -12,12 +12,6 @@ config IIO_PERIODIC_RTC_TRIGGER Provides support for using periodic capable real time clocks as IIO triggers. -config IIO_INTERRUPT_TRIGGER - tristate "Generic interrupt trigger" - help - Provides support for using interrupts of various types as IIO - triggers. These may be provided by a gpio driver for example. - config IIO_BFIN_TMR_TRIGGER tristate "Blackfin TIMER trigger" depends on BLACKFIN diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile index 48f2236147bb..238481b78e72 100644 --- a/drivers/staging/iio/trigger/Makefile +++ b/drivers/staging/iio/trigger/Makefile @@ -3,5 +3,4 @@ # obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o -obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o From 0a4510a6cbee270820871e60ab0cac7058b2f394 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 3 Jun 2013 14:30:00 +0100 Subject: [PATCH 07/15] iio: frequency: adf4350: cast value to unsigned to make code checkers happy Signed-off-by: Michael Hennerich Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/frequency/adf4350.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h index be91f344d5fc..ffd8c8f90928 100644 --- a/include/linux/iio/frequency/adf4350.h +++ b/include/linux/iio/frequency/adf4350.h @@ -1,7 +1,7 @@ /* * ADF4350/ADF4351 SPI PLL driver * - * Copyright 2012 Analog Devices Inc. + * Copyright 2012-2013 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -41,7 +41,7 @@ #define ADF4350_REG2_RDIV2_EN (1 << 24) #define ADF4350_REG2_RMULT2_EN (1 << 25) #define ADF4350_REG2_MUXOUT(x) ((x) << 26) -#define ADF4350_REG2_NOISE_MODE(x) ((x) << 29) +#define ADF4350_REG2_NOISE_MODE(x) (((unsigned)(x)) << 29) #define ADF4350_MUXOUT_THREESTATE 0 #define ADF4350_MUXOUT_DVDD 1 #define ADF4350_MUXOUT_GND 2 From 762011d6193f8b9af9b491ded87dde3221d0600a Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Mon, 3 Jun 2013 15:58:00 +0100 Subject: [PATCH 08/15] iio:common: ST_SENSORS_LSM_CHANNELS macro changed Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel_core.c | 36 ++++++++++++++++--------- drivers/iio/gyro/st_gyro_core.c | 21 ++++++++------- drivers/iio/magnetometer/st_magn_core.c | 36 ++++++++++++++++--------- include/linux/iio/common/st_sensors.h | 20 +++++++------- 4 files changed, 69 insertions(+), 44 deletions(-) diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index e0f5a3ceba5e..40236d5d8753 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -125,22 +125,34 @@ #define ST_ACCEL_3_MULTIREAD_BIT false static const struct iio_chan_spec st_accel_12bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE, - ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_X_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE, - ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE, - ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16, + ST_ACCEL_DEFAULT_OUT_X_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16, + ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16, + ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), IIO_CHAN_SOFT_TIMESTAMP(3) }; static const struct iio_chan_spec st_accel_16bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_X_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, + ST_ACCEL_DEFAULT_OUT_X_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, + ST_ACCEL_DEFAULT_OUT_Y_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, + ST_ACCEL_DEFAULT_OUT_Z_L_ADDR), IIO_CHAN_SOFT_TIMESTAMP(3) }; diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index fa9b24219987..9bae46bcccee 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -86,15 +86,18 @@ #define ST_GYRO_2_MULTIREAD_BIT true static const struct iio_chan_spec st_gyro_16bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_X, - IIO_MOD_X, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS, - ST_GYRO_DEFAULT_OUT_X_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Y, - IIO_MOD_Y, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS, - ST_GYRO_DEFAULT_OUT_Y_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Z, - IIO_MOD_Z, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS, - ST_GYRO_DEFAULT_OUT_Z_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, + ST_GYRO_DEFAULT_OUT_X_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, + ST_GYRO_DEFAULT_OUT_Y_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, + ST_GYRO_DEFAULT_OUT_Z_L_ADDR), IIO_CHAN_SOFT_TIMESTAMP(3) }; diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 16f0d6df239f..715d61681df3 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -113,22 +113,34 @@ #define ST_MAGN_2_OUT_Z_L_ADDR 0x2c static const struct iio_chan_spec st_magn_16bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_X_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Y_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Z_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, + ST_MAGN_DEFAULT_OUT_X_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, + ST_MAGN_DEFAULT_OUT_Y_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, + ST_MAGN_DEFAULT_OUT_Z_L_ADDR), IIO_CHAN_SOFT_TIMESTAMP(3) }; static const struct iio_chan_spec st_magn_2_16bit_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_X_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Y_L_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE, - ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Z_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, + ST_MAGN_2_OUT_X_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, + ST_MAGN_2_OUT_Y_L_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_MAGN, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, + ST_MAGN_2_OUT_Z_L_ADDR), IIO_CHAN_SOFT_TIMESTAMP(3) }; diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 172c5b23cb84..5ffd763702dc 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -30,8 +30,6 @@ #define ST_SENSORS_SCAN_X 0 #define ST_SENSORS_SCAN_Y 1 #define ST_SENSORS_SCAN_Z 2 -#define ST_SENSORS_DEFAULT_12_REALBITS 12 -#define ST_SENSORS_DEFAULT_16_REALBITS 16 #define ST_SENSORS_DEFAULT_POWER_ON_VALUE 0x01 #define ST_SENSORS_DEFAULT_POWER_OFF_VALUE 0x00 #define ST_SENSORS_DEFAULT_WAI_ADDRESS 0x0f @@ -42,20 +40,20 @@ #define ST_SENSORS_MAX_NAME 17 #define ST_SENSORS_MAX_4WAI 7 -#define ST_SENSORS_LSM_CHANNELS(device_type, index, mod, endian, bits, addr) \ +#define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \ + ch2, s, endian, rbits, sbits, addr) \ { \ .type = device_type, \ - .modified = 1, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_SCALE), \ + .modified = mod, \ + .info_mask_separate = mask, \ .scan_index = index, \ - .channel2 = mod, \ + .channel2 = ch2, \ .address = addr, \ .scan_type = { \ - .sign = 's', \ - .realbits = bits, \ - .shift = 16 - bits, \ - .storagebits = 16, \ + .sign = s, \ + .realbits = rbits, \ + .shift = sbits - rbits, \ + .storagebits = sbits, \ .endianness = endian, \ }, \ } From 607a568ab69c5ac345a286267a27294888f8bb5f Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Mon, 3 Jun 2013 15:58:00 +0100 Subject: [PATCH 09/15] iio:common: Removed stuff macros, added num_data_channels on st_sensors struct and added support on one-shot sysfs reads to 3 byte channel This patch introduce num_data_channels variable on st_sensors struct to manage different type of channels (size or number) in st_sensors_get_buffer_element function. Removed ST_SENSORS_NUMBER_DATA_CHANNELS and ST_SENSORS_BYTE_FOR_CHANNEL and used struct iio_chan_spec const *ch to catch data. Added 3 byte channel data support on one-shot reads. Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel_core.c | 3 + .../iio/common/st_sensors/st_sensors_buffer.c | 61 ++++++++++++------- .../iio/common/st_sensors/st_sensors_core.c | 34 ++++++++--- drivers/iio/gyro/st_gyro_core.c | 3 + drivers/iio/magnetometer/st_magn_core.c | 3 + include/linux/iio/common/st_sensors.h | 4 +- 6 files changed, 75 insertions(+), 33 deletions(-) diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 40236d5d8753..4aec121261d7 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -26,6 +26,8 @@ #include #include "st_accel.h" +#define ST_ACCEL_NUMBER_DATA_CHANNELS 3 + /* DEFAULT VALUE FOR SENSORS */ #define ST_ACCEL_DEFAULT_OUT_X_L_ADDR 0x28 #define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR 0x2a @@ -454,6 +456,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev) if (err < 0) goto st_accel_common_probe_error; + adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS; adata->multiread_bit = adata->sensor->multi_read_bit; indio_dev->channels = adata->sensor->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index 09b236d6ee89..71a2c5f63b9c 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c @@ -24,11 +24,20 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) { + u8 *addr; int i, n = 0, len; - u8 addr[ST_SENSORS_NUMBER_DATA_CHANNELS]; struct st_sensor_data *sdata = iio_priv(indio_dev); + unsigned int num_data_channels = sdata->num_data_channels; + unsigned int byte_for_channel = + indio_dev->channels[0].scan_type.storagebits >> 3; - for (i = 0; i < ST_SENSORS_NUMBER_DATA_CHANNELS; i++) { + addr = kmalloc(num_data_channels, GFP_KERNEL); + if (!addr) { + len = -ENOMEM; + goto st_sensors_get_buffer_element_error; + } + + for (i = 0; i < num_data_channels; i++) { if (test_bit(i, indio_dev->active_scan_mask)) { addr[n] = indio_dev->channels[i].address; n++; @@ -37,52 +46,58 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) switch (n) { case 1: len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, - addr[0], ST_SENSORS_BYTE_FOR_CHANNEL, buf, - sdata->multiread_bit); + addr[0], byte_for_channel, buf, sdata->multiread_bit); break; case 2: - if ((addr[1] - addr[0]) == ST_SENSORS_BYTE_FOR_CHANNEL) { + if ((addr[1] - addr[0]) == byte_for_channel) { len = sdata->tf->read_multiple_byte(&sdata->tb, - sdata->dev, addr[0], - ST_SENSORS_BYTE_FOR_CHANNEL*n, - buf, sdata->multiread_bit); + sdata->dev, addr[0], byte_for_channel * n, + buf, sdata->multiread_bit); } else { - u8 rx_array[ST_SENSORS_BYTE_FOR_CHANNEL* - ST_SENSORS_NUMBER_DATA_CHANNELS]; + u8 *rx_array; + rx_array = kmalloc(byte_for_channel * num_data_channels, + GFP_KERNEL); + if (!rx_array) { + len = -ENOMEM; + goto st_sensors_free_memory; + } + len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, addr[0], - ST_SENSORS_BYTE_FOR_CHANNEL* - ST_SENSORS_NUMBER_DATA_CHANNELS, + byte_for_channel * num_data_channels, rx_array, sdata->multiread_bit); - if (len < 0) - goto read_data_channels_error; + if (len < 0) { + kfree(rx_array); + goto st_sensors_free_memory; + } - for (i = 0; i < n * ST_SENSORS_NUMBER_DATA_CHANNELS; - i++) { + for (i = 0; i < n * num_data_channels; i++) { if (i < n) buf[i] = rx_array[i]; else buf[i] = rx_array[n + i]; } - len = ST_SENSORS_BYTE_FOR_CHANNEL*n; + kfree(rx_array); + len = byte_for_channel * n; } break; case 3: len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, - addr[0], ST_SENSORS_BYTE_FOR_CHANNEL* - ST_SENSORS_NUMBER_DATA_CHANNELS, + addr[0], byte_for_channel * num_data_channels, buf, sdata->multiread_bit); break; default: len = -EINVAL; - goto read_data_channels_error; + goto st_sensors_free_memory; } - if (len != ST_SENSORS_BYTE_FOR_CHANNEL*n) { + if (len != byte_for_channel * n) { len = -EIO; - goto read_data_channels_error; + goto st_sensors_free_memory; } -read_data_channels_error: +st_sensors_free_memory: + kfree(addr); +st_sensors_get_buffer_element_error: return len; } EXPORT_SYMBOL(st_sensors_get_buffer_element); diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index ed9bc8ae9330..865b1781df66 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -20,6 +20,11 @@ #define ST_SENSORS_WAI_ADDRESS 0x0f +static inline u32 st_sensors_get_unaligned_le24(const u8 *p) +{ + return ((s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8); +} + static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev, u8 reg_addr, u8 mask, u8 data) { @@ -112,7 +117,8 @@ st_sensors_match_odr_error: return ret; } -static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) +static int st_sensors_set_fullscale(struct iio_dev *indio_dev, + unsigned int fs) { int err, i = 0; struct st_sensor_data *sdata = iio_priv(indio_dev); @@ -273,21 +279,33 @@ st_sensors_match_scale_error: EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain); static int st_sensors_read_axis_data(struct iio_dev *indio_dev, - u8 ch_addr, int *data) + struct iio_chan_spec const *ch, int *data) { int err; - u8 outdata[ST_SENSORS_BYTE_FOR_CHANNEL]; + u8 *outdata; struct st_sensor_data *sdata = iio_priv(indio_dev); + unsigned int byte_for_channel = ch->scan_type.storagebits >> 3; + + outdata = kmalloc(byte_for_channel, GFP_KERNEL); + if (!outdata) { + err = -EINVAL; + goto st_sensors_read_axis_data_error; + } err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, - ch_addr, ST_SENSORS_BYTE_FOR_CHANNEL, + ch->address, byte_for_channel, outdata, sdata->multiread_bit); if (err < 0) - goto read_error; + goto st_sensors_free_memory; - *data = (s16)get_unaligned_le16(outdata); + if (byte_for_channel == 2) + *data = (s16)get_unaligned_le16(outdata); + else if (byte_for_channel == 3) + *data = (s32)st_sensors_get_unaligned_le24(outdata); -read_error: +st_sensors_free_memory: + kfree(outdata); +st_sensors_read_axis_data_error: return err; } @@ -307,7 +325,7 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, goto read_error; msleep((sdata->sensor->bootime * 1000) / sdata->odr); - err = st_sensors_read_axis_data(indio_dev, ch->address, val); + err = st_sensors_read_axis_data(indio_dev, ch, val); if (err < 0) goto read_error; diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index 9bae46bcccee..f9ed3488c314 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -27,6 +27,8 @@ #include #include "st_gyro.h" +#define ST_GYRO_NUMBER_DATA_CHANNELS 3 + /* DEFAULT VALUE FOR SENSORS */ #define ST_GYRO_DEFAULT_OUT_X_L_ADDR 0x28 #define ST_GYRO_DEFAULT_OUT_Y_L_ADDR 0x2a @@ -313,6 +315,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev) if (err < 0) goto st_gyro_common_probe_error; + gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS; gdata->multiread_bit = gdata->sensor->multi_read_bit; indio_dev->channels = gdata->sensor->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 715d61681df3..ebfe8f11a0c2 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -26,6 +26,8 @@ #include #include "st_magn.h" +#define ST_MAGN_NUMBER_DATA_CHANNELS 3 + /* DEFAULT VALUE FOR SENSORS */ #define ST_MAGN_DEFAULT_OUT_X_L_ADDR 0X04 #define ST_MAGN_DEFAULT_OUT_Y_L_ADDR 0X08 @@ -356,6 +358,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev) if (err < 0) goto st_magn_common_probe_error; + mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS; mdata->multiread_bit = mdata->sensor->multi_read_bit; indio_dev->channels = mdata->sensor->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 5ffd763702dc..72b26940730d 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -24,9 +24,7 @@ #define ST_SENSORS_FULLSCALE_AVL_MAX 10 #define ST_SENSORS_NUMBER_ALL_CHANNELS 4 -#define ST_SENSORS_NUMBER_DATA_CHANNELS 3 #define ST_SENSORS_ENABLE_ALL_AXIS 0x07 -#define ST_SENSORS_BYTE_FOR_CHANNEL 2 #define ST_SENSORS_SCAN_X 0 #define ST_SENSORS_SCAN_Y 1 #define ST_SENSORS_SCAN_Z 2 @@ -202,6 +200,7 @@ struct st_sensors { * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread. * @buffer_data: Data used by buffer part. * @odr: Output data rate of the sensor [Hz]. + * num_data_channels: Number of data channels used in buffer. * @get_irq_data_ready: Function to get the IRQ used for data ready signal. * @tf: Transfer function structure used by I/O operations. * @tb: Transfer buffers and mutex used by I/O operations. @@ -218,6 +217,7 @@ struct st_sensor_data { char *buffer_data; unsigned int odr; + unsigned int num_data_channels; unsigned int (*get_irq_data_ready) (struct iio_dev *indio_dev); From 217494e5b780ad85485c1bb6382ce50b5fa2dc26 Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Mon, 3 Jun 2013 15:58:00 +0100 Subject: [PATCH 10/15] iio:pressure: Add STMicroelectronics pressures driver This patch adds a generic pressure driver for STMicroelectronics pressure sensors, currently it supports: LPS331AP. Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/pressure/Kconfig | 35 +++ drivers/iio/pressure/Makefile | 10 + drivers/iio/pressure/st_pressure.h | 39 ++++ drivers/iio/pressure/st_pressure_buffer.c | 105 +++++++++ drivers/iio/pressure/st_pressure_core.c | 272 ++++++++++++++++++++++ drivers/iio/pressure/st_pressure_i2c.c | 77 ++++++ drivers/iio/pressure/st_pressure_spi.c | 76 ++++++ 9 files changed, 616 insertions(+) create mode 100644 drivers/iio/pressure/Kconfig create mode 100644 drivers/iio/pressure/Makefile create mode 100644 drivers/iio/pressure/st_pressure.h create mode 100644 drivers/iio/pressure/st_pressure_buffer.c create mode 100644 drivers/iio/pressure/st_pressure_core.c create mode 100644 drivers/iio/pressure/st_pressure_i2c.c create mode 100644 drivers/iio/pressure/st_pressure_spi.c diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index daa3dddbc77f..9af763a90d93 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -73,5 +73,6 @@ source "drivers/iio/magnetometer/Kconfig" if IIO_TRIGGER source "drivers/iio/trigger/Kconfig" endif #IIO_TRIGGER +source "drivers/iio/pressure/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index a349a9605d1f..7a3866c2d2a1 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -22,3 +22,4 @@ obj-y += imu/ obj-y += light/ obj-y += magnetometer/ obj-y += trigger/ +obj-y += pressure/ diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig new file mode 100644 index 000000000000..9427f01e1499 --- /dev/null +++ b/drivers/iio/pressure/Kconfig @@ -0,0 +1,35 @@ +# +# Pressure drivers +# +menu "Pressure Sensors" + +config IIO_ST_PRESS + tristate "STMicroelectronics pressures Driver" + depends on (I2C || SPI_MASTER) && SYSFS + select IIO_ST_SENSORS_CORE + select IIO_ST_PRESS_I2C if (I2C) + select IIO_ST_PRESS_SPI if (SPI_MASTER) + select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) + help + Say yes here to build support for STMicroelectronics pressures: + LPS331AP. + + This driver can also be built as a module. If so, will be created + these modules: + - st_pressure (core functions for the driver [it is mandatory]); + - st_pressure_i2c (necessary for the I2C devices [optional*]); + - st_pressure_spi (necessary for the SPI devices [optional*]); + + (*) one of these is necessary to do something. + +config IIO_ST_PRESS_I2C + tristate + depends on IIO_ST_PRESS + depends on IIO_ST_SENSORS_I2C + +config IIO_ST_PRESS_SPI + tristate + depends on IIO_ST_PRESS + depends on IIO_ST_SENSORS_SPI + +endmenu diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile new file mode 100644 index 000000000000..d4bb33e5c846 --- /dev/null +++ b/drivers/iio/pressure/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for industrial I/O pressure drivers +# + +obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o +st_pressure-y := st_pressure_core.o +st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o + +obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o +obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h new file mode 100644 index 000000000000..414e45ac9b9b --- /dev/null +++ b/drivers/iio/pressure/st_pressure.h @@ -0,0 +1,39 @@ +/* + * STMicroelectronics pressures driver + * + * Copyright 2013 STMicroelectronics Inc. + * + * Denis Ciocca + * v. 1.0.0 + * Licensed under the GPL-2. + */ + +#ifndef ST_PRESS_H +#define ST_PRESS_H + +#include +#include + +#define LPS331AP_PRESS_DEV_NAME "lps331ap" + +int st_press_common_probe(struct iio_dev *indio_dev); +void st_press_common_remove(struct iio_dev *indio_dev); + +#ifdef CONFIG_IIO_BUFFER +int st_press_allocate_ring(struct iio_dev *indio_dev); +void st_press_deallocate_ring(struct iio_dev *indio_dev); +int st_press_trig_set_state(struct iio_trigger *trig, bool state); +#define ST_PRESS_TRIGGER_SET_STATE (&st_press_trig_set_state) +#else /* CONFIG_IIO_BUFFER */ +static inline int st_press_allocate_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void st_press_deallocate_ring(struct iio_dev *indio_dev) +{ +} +#define ST_PRESS_TRIGGER_SET_STATE NULL +#endif /* CONFIG_IIO_BUFFER */ + +#endif /* ST_PRESS_H */ diff --git a/drivers/iio/pressure/st_pressure_buffer.c b/drivers/iio/pressure/st_pressure_buffer.c new file mode 100644 index 000000000000..f877ef8af520 --- /dev/null +++ b/drivers/iio/pressure/st_pressure_buffer.c @@ -0,0 +1,105 @@ +/* + * STMicroelectronics pressures driver + * + * Copyright 2013 STMicroelectronics Inc. + * + * Denis Ciocca + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "st_pressure.h" + +int st_press_trig_set_state(struct iio_trigger *trig, bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + + return st_sensors_set_dataready_irq(indio_dev, state); +} + +static int st_press_buffer_preenable(struct iio_dev *indio_dev) +{ + int err; + + err = st_sensors_set_enable(indio_dev, true); + if (err < 0) + goto st_press_set_enable_error; + + err = iio_sw_buffer_preenable(indio_dev); + +st_press_set_enable_error: + return err; +} + +static int st_press_buffer_postenable(struct iio_dev *indio_dev) +{ + int err; + struct st_sensor_data *pdata = iio_priv(indio_dev); + + pdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); + if (pdata->buffer_data == NULL) { + err = -ENOMEM; + goto allocate_memory_error; + } + + err = iio_triggered_buffer_postenable(indio_dev); + if (err < 0) + goto st_press_buffer_postenable_error; + + return err; + +st_press_buffer_postenable_error: + kfree(pdata->buffer_data); +allocate_memory_error: + return err; +} + +static int st_press_buffer_predisable(struct iio_dev *indio_dev) +{ + int err; + struct st_sensor_data *pdata = iio_priv(indio_dev); + + err = iio_triggered_buffer_predisable(indio_dev); + if (err < 0) + goto st_press_buffer_predisable_error; + + err = st_sensors_set_enable(indio_dev, false); + +st_press_buffer_predisable_error: + kfree(pdata->buffer_data); + return err; +} + +static const struct iio_buffer_setup_ops st_press_buffer_setup_ops = { + .preenable = &st_press_buffer_preenable, + .postenable = &st_press_buffer_postenable, + .predisable = &st_press_buffer_predisable, +}; + +int st_press_allocate_ring(struct iio_dev *indio_dev) +{ + return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &st_sensors_trigger_handler, &st_press_buffer_setup_ops); +} + +void st_press_deallocate_ring(struct iio_dev *indio_dev) +{ + iio_triggered_buffer_cleanup(indio_dev); +} + +MODULE_AUTHOR("Denis Ciocca "); +MODULE_DESCRIPTION("STMicroelectronics pressures buffer"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c new file mode 100644 index 000000000000..9c343b40665e --- /dev/null +++ b/drivers/iio/pressure/st_pressure_core.c @@ -0,0 +1,272 @@ +/* + * STMicroelectronics pressures driver + * + * Copyright 2013 STMicroelectronics Inc. + * + * Denis Ciocca + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "st_pressure.h" + +#define ST_PRESS_MBAR_TO_KPASCAL(x) (x * 10) +#define ST_PRESS_NUMBER_DATA_CHANNELS 1 + +/* DEFAULT VALUE FOR SENSORS */ +#define ST_PRESS_DEFAULT_OUT_XL_ADDR 0x28 +#define ST_TEMP_DEFAULT_OUT_L_ADDR 0x2b + +/* FULLSCALE */ +#define ST_PRESS_FS_AVL_1260MB 1260 + +/* CUSTOM VALUES FOR SENSOR 1 */ +#define ST_PRESS_1_WAI_EXP 0xbb +#define ST_PRESS_1_ODR_ADDR 0x20 +#define ST_PRESS_1_ODR_MASK 0x70 +#define ST_PRESS_1_ODR_AVL_1HZ_VAL 0x01 +#define ST_PRESS_1_ODR_AVL_7HZ_VAL 0x05 +#define ST_PRESS_1_ODR_AVL_13HZ_VAL 0x06 +#define ST_PRESS_1_ODR_AVL_25HZ_VAL 0x07 +#define ST_PRESS_1_PW_ADDR 0x20 +#define ST_PRESS_1_PW_MASK 0x80 +#define ST_PRESS_1_FS_ADDR 0x23 +#define ST_PRESS_1_FS_MASK 0x30 +#define ST_PRESS_1_FS_AVL_1260_VAL 0x00 +#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_MBAR_TO_KPASCAL(244141) +#define ST_PRESS_1_FS_AVL_TEMP_GAIN 2083000 +#define ST_PRESS_1_BDU_ADDR 0x20 +#define ST_PRESS_1_BDU_MASK 0x04 +#define ST_PRESS_1_DRDY_IRQ_ADDR 0x22 +#define ST_PRESS_1_DRDY_IRQ_MASK 0x04 +#define ST_PRESS_1_MULTIREAD_BIT true +#define ST_PRESS_1_TEMP_OFFSET 42500 + +static const struct iio_chan_spec st_press_channels[] = { + ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24, + ST_PRESS_DEFAULT_OUT_XL_ADDR), + ST_SENSORS_LSM_CHANNELS(IIO_TEMP, + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + -1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16, + ST_TEMP_DEFAULT_OUT_L_ADDR), + IIO_CHAN_SOFT_TIMESTAMP(1) +}; + +static const struct st_sensors st_press_sensors[] = { + { + .wai = ST_PRESS_1_WAI_EXP, + .sensors_supported = { + [0] = LPS331AP_PRESS_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_press_channels, + .odr = { + .addr = ST_PRESS_1_ODR_ADDR, + .mask = ST_PRESS_1_ODR_MASK, + .odr_avl = { + { 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, }, + { 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, }, + { 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, }, + { 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, }, + }, + }, + .pw = { + .addr = ST_PRESS_1_PW_ADDR, + .mask = ST_PRESS_1_PW_MASK, + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .fs = { + .addr = ST_PRESS_1_FS_ADDR, + .mask = ST_PRESS_1_FS_MASK, + .fs_avl = { + [0] = { + .num = ST_PRESS_FS_AVL_1260MB, + .value = ST_PRESS_1_FS_AVL_1260_VAL, + .gain = ST_PRESS_1_FS_AVL_1260_GAIN, + .gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN, + }, + }, + }, + .bdu = { + .addr = ST_PRESS_1_BDU_ADDR, + .mask = ST_PRESS_1_BDU_MASK, + }, + .drdy_irq = { + .addr = ST_PRESS_1_DRDY_IRQ_ADDR, + .mask = ST_PRESS_1_DRDY_IRQ_MASK, + }, + .multi_read_bit = ST_PRESS_1_MULTIREAD_BIT, + .bootime = 2, + }, +}; + +static int st_press_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *ch, int *val, + int *val2, long mask) +{ + int err; + struct st_sensor_data *pdata = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + err = st_sensors_read_info_raw(indio_dev, ch, val); + if (err < 0) + goto read_error; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + + switch (ch->type) { + case IIO_PRESSURE: + *val2 = pdata->current_fullscale->gain; + break; + case IIO_TEMP: + *val2 = pdata->current_fullscale->gain2; + break; + default: + err = -EINVAL; + goto read_error; + } + + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_OFFSET: + switch (ch->type) { + case IIO_TEMP: + *val = 425; + *val2 = 10; + break; + default: + err = -EINVAL; + goto read_error; + } + + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + +read_error: + return err; +} + +static ST_SENSOR_DEV_ATTR_SAMP_FREQ(); +static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); + +static struct attribute *st_press_attributes[] = { + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + NULL, +}; + +static const struct attribute_group st_press_attribute_group = { + .attrs = st_press_attributes, +}; + +static const struct iio_info press_info = { + .driver_module = THIS_MODULE, + .attrs = &st_press_attribute_group, + .read_raw = &st_press_read_raw, +}; + +#ifdef CONFIG_IIO_TRIGGER +static const struct iio_trigger_ops st_press_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE, +}; +#define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops) +#else +#define ST_PRESS_TRIGGER_OPS NULL +#endif + +int st_press_common_probe(struct iio_dev *indio_dev) +{ + int err; + struct st_sensor_data *pdata = iio_priv(indio_dev); + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &press_info; + + err = st_sensors_check_device_support(indio_dev, + ARRAY_SIZE(st_press_sensors), st_press_sensors); + if (err < 0) + goto st_press_common_probe_error; + + pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; + pdata->multiread_bit = pdata->sensor->multi_read_bit; + indio_dev->channels = pdata->sensor->ch; + indio_dev->num_channels = ARRAY_SIZE(st_press_channels); + + pdata->current_fullscale = (struct st_sensor_fullscale_avl *) + &pdata->sensor->fs.fs_avl[0]; + pdata->odr = pdata->sensor->odr.odr_avl[0].hz; + + err = st_sensors_init_sensor(indio_dev); + if (err < 0) + goto st_press_common_probe_error; + + if (pdata->get_irq_data_ready(indio_dev) > 0) { + err = st_press_allocate_ring(indio_dev); + if (err < 0) + goto st_press_common_probe_error; + + err = st_sensors_allocate_trigger(indio_dev, + ST_PRESS_TRIGGER_OPS); + if (err < 0) + goto st_press_probe_trigger_error; + } + + err = iio_device_register(indio_dev); + if (err) + goto st_press_device_register_error; + + return err; + +st_press_device_register_error: + if (pdata->get_irq_data_ready(indio_dev) > 0) + st_sensors_deallocate_trigger(indio_dev); +st_press_probe_trigger_error: + if (pdata->get_irq_data_ready(indio_dev) > 0) + st_press_deallocate_ring(indio_dev); +st_press_common_probe_error: + return err; +} +EXPORT_SYMBOL(st_press_common_probe); + +void st_press_common_remove(struct iio_dev *indio_dev) +{ + struct st_sensor_data *pdata = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + if (pdata->get_irq_data_ready(indio_dev) > 0) { + st_sensors_deallocate_trigger(indio_dev); + st_press_deallocate_ring(indio_dev); + } + iio_device_free(indio_dev); +} +EXPORT_SYMBOL(st_press_common_remove); + +MODULE_AUTHOR("Denis Ciocca "); +MODULE_DESCRIPTION("STMicroelectronics pressures driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c new file mode 100644 index 000000000000..7cebcc73bfb0 --- /dev/null +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -0,0 +1,77 @@ +/* + * STMicroelectronics pressures driver + * + * Copyright 2013 STMicroelectronics Inc. + * + * Denis Ciocca + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "st_pressure.h" + +static int st_press_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct st_sensor_data *pdata; + int err; + + indio_dev = iio_device_alloc(sizeof(*pdata)); + if (indio_dev == NULL) { + err = -ENOMEM; + goto iio_device_alloc_error; + } + + pdata = iio_priv(indio_dev); + pdata->dev = &client->dev; + + st_sensors_i2c_configure(indio_dev, client, pdata); + + err = st_press_common_probe(indio_dev); + if (err < 0) + goto st_press_common_probe_error; + + return 0; + +st_press_common_probe_error: + iio_device_free(indio_dev); +iio_device_alloc_error: + return err; +} + +static int st_press_i2c_remove(struct i2c_client *client) +{ + st_press_common_remove(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id st_press_id_table[] = { + { LPS331AP_PRESS_DEV_NAME }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, st_press_id_table); + +static struct i2c_driver st_press_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "st-press-i2c", + }, + .probe = st_press_i2c_probe, + .remove = st_press_i2c_remove, + .id_table = st_press_id_table, +}; +module_i2c_driver(st_press_driver); + +MODULE_AUTHOR("Denis Ciocca "); +MODULE_DESCRIPTION("STMicroelectronics pressures i2c driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c new file mode 100644 index 000000000000..17a14907940a --- /dev/null +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -0,0 +1,76 @@ +/* + * STMicroelectronics pressures driver + * + * Copyright 2013 STMicroelectronics Inc. + * + * Denis Ciocca + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "st_pressure.h" + +static int st_press_spi_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct st_sensor_data *pdata; + int err; + + indio_dev = iio_device_alloc(sizeof(*pdata)); + if (indio_dev == NULL) { + err = -ENOMEM; + goto iio_device_alloc_error; + } + + pdata = iio_priv(indio_dev); + pdata->dev = &spi->dev; + + st_sensors_spi_configure(indio_dev, spi, pdata); + + err = st_press_common_probe(indio_dev); + if (err < 0) + goto st_press_common_probe_error; + + return 0; + +st_press_common_probe_error: + iio_device_free(indio_dev); +iio_device_alloc_error: + return err; +} + +static int st_press_spi_remove(struct spi_device *spi) +{ + st_press_common_remove(spi_get_drvdata(spi)); + + return 0; +} + +static const struct spi_device_id st_press_id_table[] = { + { LPS331AP_PRESS_DEV_NAME }, + {}, +}; +MODULE_DEVICE_TABLE(spi, st_press_id_table); + +static struct spi_driver st_press_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "st-press-spi", + }, + .probe = st_press_spi_probe, + .remove = st_press_spi_remove, + .id_table = st_press_id_table, +}; +module_spi_driver(st_press_driver); + +MODULE_AUTHOR("Denis Ciocca "); +MODULE_DESCRIPTION("STMicroelectronics pressures spi driver"); +MODULE_LICENSE("GPL v2"); From d0695f4ece30b612ed67b8960fd79deab4c9dae9 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 6 Jun 2013 10:27:00 +0100 Subject: [PATCH 11/15] staging: iio: ad7606_par: Remove redundant platform_set_drvdata() Commit 0998d06310 (device-core: Ensure drvdata = NULL when no driver is bound) removes the need to set driver data field to NULL. Signed-off-by: Sachin Kamat Cc: Michael Hennerich Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7606_par.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c index 58cfddea9637..8a48d18de788 100644 --- a/drivers/staging/iio/adc/ad7606_par.c +++ b/drivers/staging/iio/adc/ad7606_par.c @@ -112,8 +112,6 @@ static int ad7606_par_remove(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); - platform_set_drvdata(pdev, NULL); - return 0; } From a4cac959042e6eaf41cc08d11162cbda4e438aac Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 6 Jun 2013 10:27:00 +0100 Subject: [PATCH 12/15] staging: iio: spear_adc: Remove redundant platform_set_drvdata() Commit 0998d06310 (device-core: Ensure drvdata = NULL when no driver is bound) removes the need to set driver data field to NULL. Signed-off-by: Sachin Kamat Acked-by: Stefan Roese Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/spear_adc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index f45da4266950..25a06cbe16c0 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -407,7 +407,6 @@ static int spear_adc_remove(struct platform_device *pdev) struct spear_adc_info *info = iio_priv(iodev); iio_device_unregister(iodev); - platform_set_drvdata(pdev, NULL); clk_disable_unprepare(info->clk); clk_put(info->clk); iounmap(info->adc_base_spear6xx); From 065792ad0dc0ae5762ad0420edf9f2ac198015ac Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 6 Jun 2013 10:27:00 +0100 Subject: [PATCH 13/15] staging: iio: lpc32xx_adc: Remove redundant platform_set_drvdata() Commit 0998d06310 (device-core: Ensure drvdata = NULL when no driver is bound) removes the need to set driver data field to NULL. Signed-off-by: Sachin Kamat Tested-by: Roland Stigge Acked-by: Roland Stigge Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/lpc32xx_adc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index 2f2f7fdd0691..9a4bb0999b51 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -215,7 +215,6 @@ static int lpc32xx_adc_remove(struct platform_device *pdev) iio_device_unregister(iodev); free_irq(irq, info); - platform_set_drvdata(pdev, NULL); clk_put(info->clk); iounmap(info->adc_base); iio_device_free(iodev); From e89b6747058748f0190a6852f53d65a7e79f4a9f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 7 Jun 2013 12:06:00 +0100 Subject: [PATCH 14/15] staging: iio: spear_adc: Add missing CONFIG_OF macro The data structure is required only when DT is enabled. Hence compile it conditionally. Signed-off-by: Sachin Kamat Acked-by: Stefan Roese Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/spear_adc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 25a06cbe16c0..736219c30308 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -415,11 +415,13 @@ static int spear_adc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF static const struct of_device_id spear_adc_dt_ids[] = { { .compatible = "st,spear600-adc", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, spear_adc_dt_ids); +#endif static struct platform_driver spear_adc_driver = { .probe = spear_adc_probe, From 78f304d06c47d600ec1a4b0995f1f4c5667a677e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Thu, 6 Jun 2013 19:27:00 +0100 Subject: [PATCH 15/15] iio:trigger:interrupt fix formatting of rsize variable in name The name includes irq_res->start which of type resource_size_t not integer. We could in theory use %pa for this but then it would be in hex and also that causes a warning about incorrect types anyway. Hence just use the irq local variable we assigned the line above. Reported-by: Fengguang Wu Signed-off-by: Jonathan Cameron --- drivers/iio/trigger/iio-trig-interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c index 84bf397ec465..02577ec54c6b 100644 --- a/drivers/iio/trigger/iio-trig-interrupt.c +++ b/drivers/iio/trigger/iio-trig-interrupt.c @@ -50,7 +50,7 @@ static int iio_interrupt_trigger_probe(struct platform_device *pdev) irq = irq_res->start; - trig = iio_trigger_alloc("irqtrig%d", irq_res->start); + trig = iio_trigger_alloc("irqtrig%d", irq); if (!trig) { ret = -ENOMEM; goto error_ret;