Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

AT91: IIO: Move the SoC specific informations to the ADC driver

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Cc: Patrice Vilchez <patrice.vilchez@atmel.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  • Loading branch information...
commit 87beb0bffb12e052f84d8aa591dd24d36e34f757 1 parent e715952
@mripard mripard authored noglitch committed
View
9 arch/arm/mach-at91/at91sam9260_devices.c
@@ -1365,15 +1365,6 @@ 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);
- /*
- * The electrical characteristics part of the AT91SAM9G20 datasheet
- * sets the ADC clock to 5MHz.
- */
- data->adc_clock = 5000000;
-
- data->num_channels = 4;
- data->startup_time = 10;
-
adc_data = *data;
platform_device_register(&at91_adc_device);
}
View
52 drivers/staging/iio/adc/at91_adc.c
@@ -24,6 +24,22 @@
#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.
+ * @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;
+ u8 num_channels;
+ u8 startup_time;
+};
struct at91_adc_state {
struct clk *clk;
@@ -35,8 +51,25 @@ struct at91_adc_state {
void __iomem *reg_base;
unsigned int vref_mv;
unsigned long channels_mask;
+ struct at91_adc_desc *desc;
+};
+
+static struct at91_adc_desc at91_adc_desc_sam9g20 = {
+ .clock = 5000000,
+ .num_channels = 4,
+ .startup_time = 10,
};
+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;
+}
+
static inline u32 at91_adc_reg_read(struct at91_adc_state *st,
u8 reg)
{
@@ -72,18 +105,19 @@ static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
static int at91_adc_channel_init(struct iio_dev *idev,
struct at91_adc_data *pdata)
{
+ struct at91_adc_state *st = iio_priv(idev);
struct iio_chan_spec *chan_array;
int bit, idx = 0;
idev->num_channels = bitmap_weight(&pdata->channels_used,
- pdata->num_channels);
+ st->desc->num_channels);
chan_array = kcalloc(idev->num_channels, sizeof(struct iio_chan_spec),
GFP_KERNEL);
if (chan_array == NULL)
return -ENOMEM;
- for_each_set_bit(bit, &pdata->channels_used, pdata->num_channels) {
+ for_each_set_bit(bit, &pdata->channels_used, st->desc->num_channels) {
struct iio_chan_spec *chan = chan_array + idx;
chan->type = IIO_VOLTAGE;
chan->indexed = 1;
@@ -186,6 +220,12 @@ static int __devinit at91_adc_probe(struct platform_device *pdev)
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");
@@ -238,7 +278,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev)
goto error_free_clk;
}
- if (!pdata->adc_clock) {
+ if (!st->desc->clock) {
dev_err(&pdev->dev, "No ADCClock available.\n");
ret = -EINVAL;
goto error_free_clk;
@@ -249,9 +289,9 @@ static int __devinit at91_adc_probe(struct platform_device *pdev)
* datasheet : ADC Clock = MCK / ((Prescaler + 1) * 2), ADC Clock being
* specified by the electrical characteristics of the board.
*/
- prsc = (mstrclk / (2 * pdata->adc_clock)) - 1;
+ prsc = (mstrclk / (2 * st->desc->clock)) - 1;
- if (!pdata->startup_time) {
+ if (!st->desc->startup_time) {
dev_err(&pdev->dev, "No startup time available.\n");
ret = -EINVAL;
goto error_free_clk;
@@ -262,7 +302,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev)
* defined in the electrical characteristics of the board, divided by 8.
* The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock
*/
- ticks = round_up((pdata->startup_time * pdata->adc_clock /
+ ticks = round_up((st->desc->startup_time * st->desc->clock /
1000000) - 1, 8) / 8;
at91_adc_reg_write(st, AT91_ADC_MR,
(AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL) |
View
20 include/linux/platform_data/at91_adc.h
@@ -15,20 +15,14 @@
#ifndef _AT91_ADC_H_
#define _AT91_ADC_H_
+/**
+ * struct at91_adc_data - platform data for ADC driver
+ * @channels_use: channels in use on the board as a bitmask
+ * @vref: Reference voltage for the ADC in millvolts
+ */
struct at91_adc_data {
- /* ADC Clock as specified by the datasheet, in Hz. */
- unsigned int adc_clock;
- /*
- * Global number of channels available (to specify which channels are
- * indeed used on the board, see the channels_used bitmask).
- */
- u8 num_channels;
- /* Channels in use on the board as a bitmask */
- unsigned long channels_used;
- /* Startup time of the ADC, in microseconds. */
- u8 startup_time;
- /* Reference voltage for the ADC in millivolts */
- unsigned short vref;
+ u32 channels_used;
+ u16 vref;
};
extern void __init at91_add_device_adc(struct at91_adc_data *data);
Please sign in to comment.
Something went wrong with that request. Please try again.