Add ADC driver for G20 and G45 evaluation boards
Subsystems (6)
PATCH 1/1 Add ADC driver for G20 and G45 evaluation boards
Hi all,
Here is the improved version of what I've been posting some time ago. Some things changed since last version:
- Support for Hardware triggers for the G20 has been added
- Support for the AT91SAM9M10G45 board has been added too, both for software and hardware triggers
- The driver is now in drivers/staging/iio to include all these features.
The first three patches should not have changed much since last post, so it should be pretty ok.
Thanks,
Maxime
PATCH 1/5 ARM: AT91: Add platform data for the AT91 ADCs
The AT91 SoCs often embeds an ADC. This patch adds the needed platform data to specify the informations required by the driver to work properly.
For now, we only need the reference voltage and which channels are available on the board.
--- include/linux/platform_data/at91_adc.h | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-) create mode 100644 include/linux/platform_data/at91_adc.h
include/linux/platform_data/at91_adc.h new file +23 -0
@@ -0,0 +1,23 @@ +/* +* Copyright (C) 2011 Free Electrons +* +* Licensed under the GPLv2 or later. +* +*/ + +#ifndef _AT91_ADC_H_ +#define _AT91_ADC_H_ + +/** +* struct at91_adc_data - platform data for ADC driver +* @channels_used: channels in use on the board as a bitmask +* @vref: Reference voltage for the ADC in millivolts +*/ +struct at91_adc_data { +unsigned long channels_used; +u16 vref; +}; + +extern void __init at91_add_device_adc (struct at91_adc_data *data); + +#endif
Signature · 1 line
1.7.5.4
Jonathan Cameron
maintainerPATCH 1/5 ARM: AT91: Add platform data for the AT91 ADCs
Quoted 6 lines · Maxime Ripard
The AT91 SoCs often embeds an ADC. This patch adds the needed platform data to specify the informations required by the driver to work properly.
For now, we only need the reference voltage and which channels are available on the board.
Trivial, though I'm in a fussy mood so see below.
Quoted 2 lines
Signed-off-by Maxime Ripard<[email protected]>
Quoted 16 lines
Cc Nicolas Ferre<[email protected]>Cc Patrice Vilchez<[email protected]>Cc Thomas Petazzoni<[email protected]>Cc Jean-Christophe PLAGNIOL-VILLARD<[email protected]>--- include/linux/platform_data/at91_adc.h | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-)create mode 100644
include/linux/platform_data/at91_adc.hinclude/linux/platform_data/at91_adc.h new file +0
-0
include/linux/platform_data/at91_adc.h line 4
Quoted 4 lines
include/linux/platform_data/at91_adc.h new file +4
-0@@ -0,0 +1,23 @@ +/* +* Copyright (C) 2011 Free Electrons +* +* Licensed under the GPLv2 or later.
If we are really being nitpicky, no point in the next blank line!
Quoted 19 lines
include/linux/platform_data/at91_adc.h new file +19
-0+* +*/ + +#ifndef _AT91_ADC_H_ +#define _AT91_ADC_H_ + +/** +* struct at91_adc_data - platform data for ADC driver +* @channels_used: channels in use on the board as a bitmask +* @vref: Reference voltage for the ADC in millivolts +*/ +struct at91_adc_data { +unsigned long channels_used; +u16 vref; +}; + +extern void __init at91_add_device_adc (struct at91_adc_data *data); + +#endif
PATCH 2/5 ARM: AT91: IIO: Add AT91 ADC driver.
In reply to Maxime RipardAdd the IIO driver for the AT91 ADCs. It only supports and has been tested on the SAM9G20 evaluation boards, but support for other boards will come eventually.
This ADC is a multi-channel ADC with support for both hardware and software triggers.
This first version only supports software triggers.
--- drivers/staging/iio/adc/Kconfig | 6 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/at91_adc.c | 382 ++++++++++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/iio/adc/at91_adc.c
drivers/staging/iio/adc/Kconfig +6 -0
@@ -169,6 +169,12 @@ config AD7280 To compile this driver as a module, choose M here: the module will be called ad7280a +config AT91_ADC + tristate "Atmel AT91 ADC" + depends on SYSFS && ARCH_AT91 + help + Say yes here to build support for Atmel AT91 ADC. + config MAX1363 tristate "Maxim max1363 ADC driver" depends on I2C
drivers/staging/iio/adc/Makefile +1 -0
@@ -38,3 +38,4 @@ obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o +obj-$(CONFIG_AT91_ADC) += at91_adc.o
drivers/staging/iio/adc/at91_adc.c new file +382 -0
382 lines not on this page · raw message
Signature · 1 line
1.7.5.4
PATCH 2/5 ARM: AT91: IIO: Add AT91 ADC driver.
Quoted 105 lines · Maxime Ripard
Add the IIO driver for the AT91 ADCs. It only supports and has been tested on the SAM9G20 evaluation boards, but support for other boards will come eventually.
This ADC is a multi-channel ADC with support for both hardware and software triggers.
This first version only supports software triggers.
Signed-off-by Maxime Ripard <[email protected]>Cc Nicolas Ferre <[email protected]>Cc Jean-Christophe PLAGNIOL-VILLARD <[email protected]>Cc Patrice Vilchez <[email protected]>Cc Thomas Petazzoni <[email protected]>Cc Jonathan Cameron <[email protected]>--- drivers/staging/iio/adc/Kconfig | 6 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/at91_adc.c | 382 ++++++++++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/iio/adc/at91_adc.cdrivers/staging/iio/adc/Kconfig +6
-0@@ -169,6 +169,12 @@ config AD7280 To compile this driver as a module, choose M here: the module will be called ad7280a +config AT91_ADC + tristate "Atmel AT91 ADC" + depends on SYSFS && ARCH_AT91 + help + Say yes here to build support for Atmel AT91 ADC. + config MAX1363 tristate "Maxim max1363 ADC driver" depends on I2Cdrivers/staging/iio/adc/Makefile +1
-0@@ -38,3 +38,4 @@ obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o +obj-$(CONFIG_AT91_ADC) += at91_adc.odrivers/staging/iio/adc/at91_adc.c new file +50
-0@@ -0,0 +1,382 @@ +/* +* Driver for the ADC present in the Atmel AT91 evaluation boards. +* +* Copyright 2011 Free Electrons +* +* Licensed under the GPLv2 or later. +*/ + +#include <linux/bitmap.h> +#include <linux/bitops.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/wait.h> + +#include "../iio.h" +#include <linux/platform_data/at91_adc.h> + +#include <mach/at91_adc.h> +#include <mach/cpu.h> + +/** +* struct at91_adc_desc - description of the ADC on the board +* @clock: ADC clock as specified by the datasheet, in Hz. +* @clock_name Name of the ADC clock as defined in the clock tree +* @num_channels: global number of channels available on the board (to +specify which channels are indeed in use on the +board, see the channels_used bitmask in the platform +data) +* @startup_time: startup time of the ADC in microseconds +*/ +struct at91_adc_desc { +u32 clock; +char *clock_name; +u8 num_channels; +u8 startup_time; +}; + +struct at91_adc_state { +unsigned long channels_mask; +struct clk *clk; +bool done; +struct at91_adc_desc *desc;
drivers/staging/iio/adc/at91_adc.c line 60
Quoted 10 lines
drivers/staging/iio/adc/at91_adc.c new file +10
-0+int irq; +u16 last_value; +struct mutex lock; +void __iomem *reg_base; +u32 vref_mv; +wait_queue_head_t wq_data_avail; +}; + +static struct at91_adc_desc at91_adc_desc_sam9g20 = { + .clock =5000000 ,
why 5Mhz?
drivers/staging/iio/adc/at91_adc.c line 65
Quoted 5 lines
drivers/staging/iio/adc/at91_adc.c new file +5
-0+ .clock_name = "adc_clk", + .num_channels = 4, + .startup_time = 10, +}; +
this is soc specific nedd to be in the soc not in the driver
drivers/staging/iio/adc/at91_adc.c line 74
Quoted 9 lines
drivers/staging/iio/adc/at91_adc.c new file +9
-0+static int at91_adc_select_soc (struct at91_adc_state *st) +{ +if (cpu_is_at91sam9g20 ()) { + st->desc = &at91_adc_desc_sam9g20; +return 0 ; + } + +return -ENODEV ; +}
ditto
Quoted 66 lines
drivers/staging/iio/adc/at91_adc.c new file +65
-0+ + +static int __devinit at91_adc_probe (struct platform_device *pdev) +{ +unsigned int prsc, mstrclk, ticks; +int ret; +struct iio_dev *idev; +struct at91_adc_state *st; +struct resource *res; +struct at91_adc_data *pdata = pdev->dev.platform_data; + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!res) { +dev_err (&pdev->dev,"No resource defined\n" ); + ret = -ENXIO ; + goto error_ret; + } + + idev =iio_allocate_device (sizeof (struct at91_adc_state )); +if (idev ==NULL ) { + ret = -ENOMEM ; + goto error_ret; + } + +platform_set_drvdata (pdev, idev); + + idev->dev.parent = &pdev->dev; + idev->name =dev_name (&pdev->dev); + idev->modes =INDIO_DIRECT_MODE ; + idev->info = &at91_adc_info; + + st =iio_priv (idev); + ret =at91_adc_select_soc (st); +if (ret) { +dev_err (&pdev->dev,"SoC unknown\n" ); + goto error_free_device; + } + + st->irq =platform_get_irq (pdev,0 ); +if (st->irq <0 ) { +dev_err (&pdev->dev,"No IRQ ID is designated\n" ); + ret = -ENODEV ; + goto error_free_device; + } + +if (!request_mem_region (res->start,resource_size (res), +"AT91 adc registers" )) { +dev_err (&pdev->dev,"Resources are unavailable.\n" ); + ret = -EBUSY ; + goto error_free_device; + } + + st->reg_base =ioremap (res->start,resource_size (res)); +if (!st->reg_base) { +dev_err (&pdev->dev,"Failed to map registers.\n" ); + ret = -ENOMEM ; + goto error_release_mem; + } + +/* +* Disable all IRQs before setting up the handler +*/ +at91_adc_reg_write (st,AT91_ADC_CR ,AT91_ADC_SWRST ); +at91_adc_reg_write (st,AT91_ADC_IDR ,0xFFFFFFFF ); + ret = request_irq(st->irq,
drivers/staging/iio/adc/at91_adc.c line 268
Quoted 10 lines
drivers/staging/iio/adc/at91_adc.c new file +10
-0+ at91_adc_eoc_trigger, +0 , + pdev->dev.driver->name, + idev); +if (ret) { +dev_err (&pdev->dev,"Failed to allocate IRQ.\n" ); + goto error_unmap_reg; + } + + st->clk =clk_get (&pdev->dev, st->desc->clock_name);
use a fixed clock name
drivers/staging/iio/adc/at91_adc.c line 274
Quoted 6 lines
drivers/staging/iio/adc/at91_adc.c new file +6
-0+if (IS_ERR (st->clk)) { +dev_err (&pdev->dev,"Failed to get the clock.\n" ); + ret =PTR_ERR (st->clk); + goto error_free_irq; + } +
use clk_prepare & co
drivers/staging/iio/adc/at91_adc.c line 282
Quoted 8 lines
drivers/staging/iio/adc/at91_adc.c new file +8
-0+clk_enable (st->clk); + mstrclk =clk_get_rate (st->clk); + +if (!pdata) { +dev_err (&pdev->dev,"No platform data available.\n" ); + ret = -EINVAL ; + goto error_free_clk; + }
need to be check first
Best Regards,
J.
PATCH 2/5 ARM: AT91: IIO: Add AT91 ADC driver.
Hi,
Le 07/04/2012 05:27, Jean-Christophe PLAGNIOL-VILLARD a ?crit :
Quoted 109 lines · Maxime Ripard
Quoted 108 lines
Add the IIO driver for the AT91 ADCs. It only supports and has been tested on the SAM9G20 evaluation boards, but support for other boards will come eventually.
This ADC is a multi-channel ADC with support for both hardware and software triggers.
This first version only supports software triggers.
Signed-off-by Maxime Ripard <[email protected]>Cc Nicolas Ferre <[email protected]>Cc Jean-Christophe PLAGNIOL-VILLARD <[email protected]>Cc Patrice Vilchez <[email protected]>Cc Thomas Petazzoni <[email protected]>Cc Jonathan Cameron <[email protected]>--- drivers/staging/iio/adc/Kconfig | 6 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/at91_adc.c | 382 ++++++++++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/iio/adc/at91_adc.cdrivers/staging/iio/adc/Kconfig +6
-0@@ -169,6 +169,12 @@ config AD7280 To compile this driver as a module, choose M here: the module will be called ad7280a +config AT91_ADC + tristate "Atmel AT91 ADC" + depends on SYSFS && ARCH_AT91 + help + Say yes here to build support for Atmel AT91 ADC. + config MAX1363 tristate "Maxim max1363 ADC driver" depends on I2Cdrivers/staging/iio/adc/Makefile +1
-0@@ -38,3 +38,4 @@ obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o +obj-$(CONFIG_AT91_ADC) += at91_adc.odrivers/staging/iio/adc/at91_adc.c new file +53
-0@@ -0,0 +1,382 @@ +/* +* Driver for the ADC present in the Atmel AT91 evaluation boards. +* +* Copyright 2011 Free Electrons +* +* Licensed under the GPLv2 or later. +*/ + +#include <linux/bitmap.h> +#include <linux/bitops.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/wait.h> + +#include "../iio.h" +#include <linux/platform_data/at91_adc.h> + +#include <mach/at91_adc.h> +#include <mach/cpu.h> + +/** +* struct at91_adc_desc - description of the ADC on the board +* @clock: ADC clock as specified by the datasheet, in Hz. +* @clock_name Name of the ADC clock as defined in the clock tree +* @num_channels: global number of channels available on the board (to +specify which channels are indeed in use on the +board, see the channels_used bitmask in the platform +data) +* @startup_time: startup time of the ADC in microseconds +*/ +struct at91_adc_desc { +u32 clock; +char *clock_name; +u8 num_channels; +u8 startup_time; +}; + +struct at91_adc_state { +unsigned long channels_mask; +struct clk *clk; +bool done; +struct at91_adc_desc *desc; +int irq; +u16 last_value; +struct mutex lock;
Quoted 8 lines
drivers/staging/iio/adc/at91_adc.c line 60
Quoted 7 lines
drivers/staging/iio/adc/at91_adc.c new file +7
-0+void __iomem *reg_base; +u32 vref_mv; +wait_queue_head_t wq_data_avail; +}; + +static struct at91_adc_desc at91_adc_desc_sam9g20 = { + .clock =5000000 ,why 5Mhz?
This is the value given by the datasheet of the G20 SoC.
Quoted 6 lines
drivers/staging/iio/adc/at91_adc.c line 65
Quoted 5 lines
drivers/staging/iio/adc/at91_adc.c new file +5
-0+ .clock_name = "adc_clk", + .num_channels = 4, + .startup_time = 10, +}; +this is soc specific nedd to be in the soc not in the driver
Some time ago, Nicolas Ferre asked me to move the SoC specific part to the driver, mostly because of two things:
* *_devices.c files were suppose to disappear with the DT
* Triggers are not all supported by the driver, so only the driver
knows which triggers it can expose (pen-down or periodic triggers for the G45 are not supported for example). This can't be done through the SoC files.
Quoted 79 lines
drivers/staging/iio/adc/at91_adc.c line 74
Quoted 9 lines
drivers/staging/iio/adc/at91_adc.c new file +9
-0+static int at91_adc_select_soc (struct at91_adc_state *st) +{ +if (cpu_is_at91sam9g20 ()) { + st->desc = &at91_adc_desc_sam9g20; +return 0 ; + } + +return -ENODEV ; +}ditto
Quoted 69 lines
drivers/staging/iio/adc/at91_adc.c new file +68
-0+ + +static int __devinit at91_adc_probe (struct platform_device *pdev) +{ +unsigned int prsc, mstrclk, ticks; +int ret; +struct iio_dev *idev; +struct at91_adc_state *st; +struct resource *res; +struct at91_adc_data *pdata = pdev->dev.platform_data; + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!res) { +dev_err (&pdev->dev,"No resource defined\n" ); + ret = -ENXIO ; + goto error_ret; + } + + idev =iio_allocate_device (sizeof (struct at91_adc_state )); +if (idev ==NULL ) { + ret = -ENOMEM ; + goto error_ret; + } + +platform_set_drvdata (pdev, idev); + + idev->dev.parent = &pdev->dev; + idev->name =dev_name (&pdev->dev); + idev->modes =INDIO_DIRECT_MODE ; + idev->info = &at91_adc_info; + + st =iio_priv (idev); + ret =at91_adc_select_soc (st); +if (ret) { +dev_err (&pdev->dev,"SoC unknown\n" ); + goto error_free_device; + } + + st->irq =platform_get_irq (pdev,0 ); +if (st->irq <0 ) { +dev_err (&pdev->dev,"No IRQ ID is designated\n" ); + ret = -ENODEV ; + goto error_free_device; + } + +if (!request_mem_region (res->start,resource_size (res), +"AT91 adc registers" )) { +dev_err (&pdev->dev,"Resources are unavailable.\n" ); + ret = -EBUSY ; + goto error_free_device; + } + + st->reg_base =ioremap (res->start,resource_size (res)); +if (!st->reg_base) { +dev_err (&pdev->dev,"Failed to map registers.\n" ); + ret = -ENOMEM ; + goto error_release_mem; + } + +/* +* Disable all IRQs before setting up the handler +*/ +at91_adc_reg_write (st,AT91_ADC_CR ,AT91_ADC_SWRST ); +at91_adc_reg_write (st,AT91_ADC_IDR ,0xFFFFFFFF ); + ret = request_irq(st->irq, + at91_adc_eoc_trigger, + 0, + pdev->dev.driver->name,
Quoted 8 lines
drivers/staging/iio/adc/at91_adc.c line 268
Quoted 7 lines
drivers/staging/iio/adc/at91_adc.c new file +7
-0+ idev); +if (ret) { +dev_err (&pdev->dev,"Failed to allocate IRQ.\n" ); + goto error_unmap_reg; + } + + st->clk =clk_get (&pdev->dev, st->desc->clock_name);use a fixed clock name
I can't. The clock name is "adc_clk" for the G20, "tsc_clk" for the G45.
Quoted 7 lines
drivers/staging/iio/adc/at91_adc.c line 274
Quoted 6 lines
drivers/staging/iio/adc/at91_adc.c new file +6
-0+if (IS_ERR (st->clk)) { +dev_err (&pdev->dev,"Failed to get the clock.\n" ); + ret =PTR_ERR (st->clk); + goto error_free_irq; + } +use
clk_prepare& co
Ok, I will look into this.
Quoted 9 lines
drivers/staging/iio/adc/at91_adc.c line 282
Quoted 8 lines
drivers/staging/iio/adc/at91_adc.c new file +8
-0+clk_enable (st->clk); + mstrclk =clk_get_rate (st->clk); + +if (!pdata) { +dev_err (&pdev->dev,"No platform data available.\n" ); + ret = -EINVAL ; + goto error_free_clk; + }need to be check first
Ok
Thanks,
Maxime
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 3/5 ARM: AT91: Add the ADC to the sam9g20ek board
In reply to Maxime RipardThis patch adds platform data for the AT91 ADC driver support for the AT91SAM9G20-EK board.
--- arch/arm/mach-at91/at91sam9260_devices.c | 53 ++++++++++++++++++++++++++++++ arch/arm/mach-at91/board-sam9g20ek.c | 13 +++++++ 2 files changed, 66 insertions(+), 0 deletions(-)
arch/arm/mach-at91/at91sam9260_devices.c +53 -0
@@ -17,6 +17,8 @@#include <linux/platform_device.h> #include <linux/i2c-gpio.h> +#include <linux/platform_data/at91_adc.h> +#include <mach/board.h> #include <mach/cpu.h> #include <mach/at91sam9260.h>
@@ -1366,6 +1368,57 @@ void __init at91_add_device_cf(struct at91_cf_data *data)void __init at91_add_device_cf (struct at91_cf_data * data) {}#endif +/* -------------------------------------------------------------------- +* ADCs +* -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_ADC ) || defined(CONFIG_AT91_ADC_MODULE ) +static struct at91_adc_data adc_data; + +static struct resource adc_resources[] = { + [0 ] = { + .start =AT91SAM9260_BASE_ADC , + .end =AT91SAM9260_BASE_ADC +SZ_16K -1 , + .flags =IORESOURCE_MEM , + }, + [1 ] = { + .start =AT91SAM9260_ID_ADC , + .end =AT91SAM9260_ID_ADC , + .flags =IORESOURCE_IRQ , + }, +}; + +static struct platform_device at91_adc_device = { + .name ="at91_adc" , + .id =-1 , + .dev = { + .platform_data = &adc_data, + }, + .resource = adc_resources, + .num_resources =ARRAY_SIZE (adc_resources), +}; + +void __init at91_add_device_adc (struct at91_adc_data *data) +{ +if (!data) +return ; + +if (test_bit (0 , &data->channels_used)) +at91_set_A_periph (AT91_PIN_PC0 ,0 ); +if (test_bit (1 , &data->channels_used)) +at91_set_A_periph (AT91_PIN_PC1 ,0 ); +if (test_bit (2 , &data->channels_used)) +at91_set_A_periph (AT91_PIN_PC2 ,0 ); +if (test_bit (3 , &data->channels_used)) +at91_set_A_periph (AT91_PIN_PC3 ,0 ); + + adc_data = *data; +platform_device_register (&at91_adc_device); +} +#else +void __init at91_add_device_adc (struct at91_adc_data *data) {} +#endif +/* -------------------------------------------------------------------- */ /* * These devices are always present and don't need any board-specific
arch/arm/mach-at91/board-sam9g20ek.c +13 -0
@@ -32,6 +32,8 @@#include <linux/regulator/fixed.h> #include <linux/regulator/consumer.h> +#include <linux/platform_data/at91_adc.h> +#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h>
@@ -318,6 +320,15 @@ static void __init ek_add_device_buttons(void)static void __init ek_add_device_buttons (void ) {}#endif +/* +* ADCs +*/ + +static struct at91_adc_data ek_adc_data = { + .channels_used =BIT (0 ) |BIT (1 ) |BIT (2 ) |BIT (3 ), + .vref =3300 , +}; +#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE ) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE )static struct regulator_consumer_supply ek_audio_consumer_supplies[] = { REGULATOR_SUPPLY("AVDD", "0-001b"),
@@ -393,6 +404,8 @@ static void __init ek_board_init(void)ek_add_device_gpio_leds ();/* Push Buttons */ ek_add_device_buttons (); +/* ADCs */ +at91_add_device_adc (&ek_adc_data);/* PCK0 provides MCLK to the WM8731 */ at91_set_B_periph (AT91_PIN_PC1 ,0 );/* SSC (for WM8731) */
Signature · 1 line
1.7.5.4
PATCH 3/5 ARM: AT91: Add the ADC to the sam9g20ek board
Quoted 4 lines · Maxime Ripard
This patch adds platform data for the AT91 ADC driver support for the AT91SAM9G20-EK board.
Signed-off-by Maxime Ripard <[email protected]>
Do you have a plan for DT?
Best Regards,
J.
PATCH 3/5 ARM: AT91: Add the ADC to the sam9g20ek board
Le 07/04/2012 05:29, Jean-Christophe PLAGNIOL-VILLARD a ?crit :
Quoted 6 lines · Maxime Ripard
Quoted 4 lines
This patch adds platform data for the AT91 ADC driver support for the AT91SAM9G20-EK board.
Signed-off-by Maxime Ripard <[email protected]>Do you have a plan for DT?
My plan was to take a look at it while adding support for the X25 and X35, presumably this week or next week.
I admit I have not looked much into it for now.
Maxime
Signature · 4 lines
Maxime Ripard, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 4/5 IIO: AT91: ADC: Add support for the AT91SAM9M10G45-EK board
In reply to Maxime RipardThis patch adds the necessary logic and the required platform_data to support the ADC present in the AT91SAM9M10G45-EK board from Atmel. It only supports software triggers for now.
--- arch/arm/mach-at91/at91sam9g45_devices.c | 61 ++++++++++++++++++++++++++++++ arch/arm/mach-at91/board-sam9m10g45ek.c | 11 +++++ drivers/staging/iio/adc/at91_adc.c | 12 ++++++ 3 files changed, 84 insertions(+), 0 deletions(-)
arch/arm/mach-at91/at91sam9g45_devices.c +61 -0
@@ -19,6 +19,8 @@#include <linux/i2c-gpio.h> #include <linux/atmel-mci.h> +#include <linux/platform_data/at91_adc.h> +#include <linux/fb.h> #include <video/atmel_lcdc.h>
@@ -1202,6 +1204,65 @@ void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}/* -------------------------------------------------------------------- +* ADC +* -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_ADC ) || defined(CONFIG_AT91_ADC_MODULE ) +static struct at91_adc_data adc_data; + +static struct resource adc_resources[] = { + [0 ] = { + .start =AT91SAM9G45_BASE_TSC , + .end =AT91SAM9G45_BASE_TSC +SZ_16K -1 , + .flags =IORESOURCE_MEM , + }, + [1 ] = { + .start =AT91SAM9G45_ID_TSC , + .end =AT91SAM9G45_ID_TSC , + .flags =IORESOURCE_IRQ , + } +}; + +static struct platform_device at91_adc_device = { + .name ="at91_adc" , + .id =-1 , + .dev = { + .platform_data = &adc_data, + }, + .resource = adc_resources, + .num_resources =ARRAY_SIZE (adc_resources), +}; + +void __init at91_add_device_adc (struct at91_adc_data *data) +{ +if (!data) +return ; + +if (test_bit (0 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD20 ,0 ); +if (test_bit (1 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD21 ,0 ); +if (test_bit (2 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD22 ,0 ); +if (test_bit (3 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD23 ,0 ); +if (test_bit (4 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD24 ,0 ); +if (test_bit (5 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD25 ,0 ); +if (test_bit (6 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD26 ,0 ); +if (test_bit (7 , &data->channels_used)) +at91_set_gpio_input (AT91_PIN_PD27 ,0 ); + + adc_data = *data; +platform_device_register (&at91_adc_device); +} +#else +void __init at91_add_device_adc (struct at91_adc_data *data) {} +#endif + +/* -------------------------------------------------------------------- * RTT * -------------------------------------------------------------------- */
arch/arm/mach-at91/board-sam9m10g45ek.c +11 -0
@@ -27,6 +27,8 @@#include <linux/atmel-mci.h> #include <linux/delay.h> +#include <linux/platform_data/at91_adc.h> +#include <mach/hardware.h> #include <video/atmel_lcdc.h> #include <media/soc_camera.h>
@@ -314,6 +316,13 @@ static struct at91_tsadcc_data ek_tsadcc_data = { .ts_sample_hold_time = 0x0a, }; +/* +* ADCs +*/ +static struct at91_adc_data ek_adc_data = { + .channels_used =BIT (0 ) |BIT (1 ) |BIT (2 ) |BIT (3 ) |BIT (4 ) |BIT (5 ) |BIT (6 ) |BIT (7 ), + .vref =3300 , +};/* * GPIO Buttons
@@ -479,6 +488,8 @@ static void __init ek_board_init(void)at91_add_device_lcdc (&ek_lcdc_data);/* Touch Screen */ at91_add_device_tsadcc (&ek_tsadcc_data); +/* ADC */ +at91_add_device_adc (&ek_adc_data);/* Push Buttons */ ek_add_device_buttons ();/* AC97 */
drivers/staging/iio/adc/at91_adc.c +12 -0
@@ -56,6 +56,13 @@ struct at91_adc_state {wait_queue_head_t wq_data_avail; }; +static struct at91_adc_desc at91_adc_desc_sam9g45 = { + .clock =13200000 , + .clock_name ="tsc_clk" , + .num_channels =8 , + .startup_time =40 , +}; +static struct at91_adc_desc at91_adc_desc_sam9g20 = { .clock =5000000 , .clock_name ="adc_clk" ,
@@ -70,6 +77,11 @@ static int at91_adc_select_soc(struct at91_adc_state *st)return 0 ; } +if (cpu_is_at91sam9g45 ()) { + st->desc = &at91_adc_desc_sam9g45; +return 0 ; + } +return -ENODEV ; }
Signature · 1 line
1.7.5.4
PATCH 4/5 IIO: AT91: ADC: Add support for the AT91SAM9M10G45-EK board
Quoted 56 lines
arch/arm/mach-at91/board-sam9m10g45ek.c +11
-0@@ -27,6 +27,8 @@#include <linux/atmel-mci.h> #include <linux/delay.h> +#include <linux/platform_data/at91_adc.h> +#include <mach/hardware.h> #include <video/atmel_lcdc.h> #include <media/soc_camera.h> @@ -314,6 +316,13 @@ static struct at91_tsadcc_data ek_tsadcc_data = { .ts_sample_hold_time = 0x0a, }; +/* +* ADCs +*/ +static struct at91_adc_data ek_adc_data = { + .channels_used =BIT (0 ) |BIT (1 ) |BIT (2 ) |BIT (3 ) |BIT (4 ) |BIT (5 ) |BIT (6 ) |BIT (7 ), + .vref =3300 , +};/* * GPIO Buttons @@ -479,6 +488,8 @@ static void __init ek_board_init(void)at91_add_device_lcdc (&ek_lcdc_data);/* Touch Screen */ at91_add_device_tsadcc (&ek_tsadcc_data); +/* ADC */ +at91_add_device_adc (&ek_adc_data);/* Push Buttons */ ek_add_device_buttons ();/* AC97 */ drivers/staging/iio/adc/at91_adc.c +7
-0@@ -56,6 +56,13 @@ struct at91_adc_state {wait_queue_head_t wq_data_avail; }; +static struct at91_adc_desc at91_adc_desc_sam9g45 = { + .clock =13200000 , + .clock_name ="tsc_clk" , + .num_channels =8 , + .startup_time =40 , +}; +static struct at91_adc_desc at91_adc_desc_sam9g20 = { .clock =5000000 , .clock_name ="adc_clk" ,@@ -70,6 +77,11 @@ static int at91_adc_select_soc(struct at91_adc_state *st)return 0 ;
drivers/staging/iio/adc/at91_adc.c static int at91_adc_select_soc(struct at91_adc_state *st) · line 87
Quoted 10 lines
drivers/staging/iio/adc/at91_adc.c +5
-0} +if (cpu_is_at91sam9g45 ()) { + st->desc = &at91_adc_desc_sam9g45; +return 0 ; + } +return -ENODEV ; }
soc specific
Best Regards,
J.
PATCH 5/5 IIO: AT91: Add support for hardware triggers for the ADC
In reply to Maxime RipardThis patch adds support for the hardware triggers for both the AT91SAM9G20-EK and AT91SAM9M10G45-EK evaluation board from Atmel.
--- arch/arm/mach-at91/at91sam9260_devices.c | 3 + arch/arm/mach-at91/at91sam9g45_devices.c | 3 + arch/arm/mach-at91/board-sam9g20ek.c | 1 + arch/arm/mach-at91/board-sam9m10g45ek.c | 1 + drivers/staging/iio/adc/Kconfig | 3 + drivers/staging/iio/adc/at91_adc.c | 390 +++++++++++++++++++++++++++++- include/linux/platform_data/at91_adc.h | 2 + 7 files changed, 396 insertions(+), 7 deletions(-)
arch/arm/mach-at91/at91sam9260_devices.c +3 -0
@@ -1412,6 +1412,9 @@ void __init at91_add_device_adc(struct at91_adc_data *data)if (test_bit (3 , &data->channels_used))at91_set_A_periph (AT91_PIN_PC3 ,0 ); +if (data->use_external) +at91_set_A_periph (AT91_PIN_PA22 ,0 ); + adc_data = *data;platform_device_register (&at91_adc_device); }
arch/arm/mach-at91/at91sam9g45_devices.c +3 -0
@@ -1255,6 +1255,9 @@ void __init at91_add_device_adc(struct at91_adc_data *data)if (test_bit (7 , &data->channels_used))at91_set_gpio_input (AT91_PIN_PD27 ,0 ); +if (data->use_external) +at91_set_A_periph (AT91_PIN_PD28 ,0 ); + adc_data = *data;platform_device_register (&at91_adc_device); }
arch/arm/mach-at91/board-sam9g20ek.c +1 -0
@@ -326,6 +326,7 @@ static void __init ek_add_device_buttons(void) {}static struct at91_adc_data ek_adc_data = { .channels_used =BIT (0 ) |BIT (1 ) |BIT (2 ) |BIT (3 ), + .use_external = true, .vref =3300 , };
arch/arm/mach-at91/board-sam9m10g45ek.c +1 -0
@@ -321,6 +321,7 @@ static struct at91_tsadcc_data ek_tsadcc_data = {*/ static struct at91_adc_data ek_adc_data = { .channels_used =BIT (0 ) |BIT (1 ) |BIT (2 ) |BIT (3 ) |BIT (4 ) |BIT (5 ) |BIT (6 ) |BIT (7 ), + .use_external = true, .vref =3300 , };
drivers/staging/iio/adc/Kconfig +3 -0
@@ -172,6 +172,9 @@ config AD7280 config AT91_ADC tristate "Atmel AT91 ADC" depends on SYSFS && ARCH_AT91 + select IIO_BUFFER + select IIO_SW_RING + select IIO_TRIGGER help Say yes here to build support for Atmel AT91 ADC.
drivers/staging/iio/adc/at91_adc.c +383 -7
495 lines not on this page · raw message
include/linux/platform_data/at91_adc.h +2 -0
@@ -11,10 +11,12 @@/** * struct at91_adc_data - platform data for ADC driver * @channels_used: channels in use on the board as a bitmask +* @use_external: does the board has external triggers availables * @vref: Reference voltage for the ADC in millivolts */ struct at91_adc_data {unsigned long channels_used; +bool use_external;u16 vref; };
Signature · 1 line
1.7.5.4
PATCH 5/5 IIO: AT91: Add support for hardware triggers for the ADC
Quoted 64 lines
drivers/staging/iio/adc/at91_adc.c +54
-0+static struct at91_adc_trigger at91_adc_trigger_sam9g45[] = { + [0 ] = { + .name ="external-rising" , + .value =AT91_TSADCC_TRGMOD_EXT_RISING , + .is_external = true, + }, + [1 ] = { + .name ="external-falling" , + .value =AT91_TSADCC_TRGMOD_EXT_FALLING , + .is_external = true, + }, + [2 ] = { + .name ="external-any" , + .value =AT91_TSADCC_TRGMOD_EXT_ANY , + .is_external = true, + }, + [3 ] = { + .name ="continuous" , + .value =AT91_TSADCC_TRGMOD_CONTINUOUS , + .is_external = false, + }, + [4 ] = { + .name =NULL , + }, +}; +static struct at91_adc_desc at91_adc_desc_sam9g45 = { .clock =13200000 , .clock_name ="tsc_clk" , .num_channels =8 , .startup_time =40 , + .triggers = at91_adc_trigger_sam9g45, + .trigger_register =AT91_TSADCC_TRGR , +}; + +static struct at91_adc_trigger at91_adc_trigger_sam9g20[] = { + [0 ] = { + .name ="timer-counter-0" , + .value =AT91_ADC_TRGSEL_TC0 |AT91_ADC_TRGEN , + .is_external = false, + }, + [1 ] = { + .name ="timer-counter-1" , + .value =AT91_ADC_TRGSEL_TC1 |AT91_ADC_TRGEN , + .is_external = false, + }, + [2 ] = { + .name ="timer-counter-2" , + .value =AT91_ADC_TRGSEL_TC2 |AT91_ADC_TRGEN , + .is_external = false, + }, + [3 ] = { + .name ="external" , + .value =AT91_ADC_TRGSEL_EXTERNAL |AT91_ADC_TRGEN , + .is_external = true, + }, + [4 ] = { + .name =NULL , + }, };static struct at91_adc_desc at91_adc_desc_sam9g20 = {
drivers/staging/iio/adc/at91_adc.c static struct at91_adc_desc at91_adc_desc_sam9g20 = { · line 158
Quoted 6 lines
drivers/staging/iio/adc/at91_adc.c +2
-0@@ -68,6 +153,8 @@ static struct at91_adc_desc at91_adc_desc_sam9g20 = { .clock_name = "adc_clk", .num_channels = 4, .startup_time = 10, + .triggers = at91_adc_trigger_sam9g20, + .trigger_register = AT91_ADC_MR, };
same comment as before this soc specific
Best Regards,
J.
drivers/staging/iio/adc/at91_adc.c static int at91_adc_channel_init(struct iio_dev *idev, · line 263
Quoted 11 lines
drivers/staging/iio/adc/at91_adc.c +3
-2@@ -125,8 +257,9 @@ static int at91_adc_channel_init(struct iio_dev *idev,int bit, idx =0 ; idev->num_channels =bitmap_weight (&pdata->channels_used, - st->desc->num_channels); - chan_array =kcalloc (idev->num_channels,sizeof (struct iio_chan_spec ), + st->desc->num_channels) +1 ; + chan_array =kcalloc (idev->num_channels +1 , +sizeof (struct iio_chan_spec ),GFP_KERNEL );
devm_kzalloc
drivers/staging/iio/adc/at91_adc.c static int at91_adc_channel_init(struct iio_dev *idev, · line 279
Quoted 13 lines
drivers/staging/iio/adc/at91_adc.c +1
-0if (chan_array ==NULL )@@ -137,6 +270,7 @@ static int at91_adc_channel_init(struct iio_dev *idev, chan->type =IIO_VOLTAGE ; chan->indexed =1 ; chan->channel = bit; + chan->scan_index = idx; chan->scan_type.sign ='u' ; chan->scan_type.realbits =10 ; chan->scan_type.storagebits =16 ;@@ -144,6 +278,13 @@ static int at91_adc_channel_init(struct iio_dev *idev, idx++; }
Best Regards,
J.