diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/boot/dts/at91sam9g45.dtsi | 37 | ||||
-rw-r--r-- | arch/arm/boot/dts/at91sam9x5.dtsi | 38 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9260.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9260_devices.c | 90 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9g45.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9g45_devices.c | 101 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9x5.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-at91/board-sam9g20ek.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-at91/board-sam9m10g45ek.c | 12 |
9 files changed, 315 insertions, 0 deletions
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index c8042147eaa..7dbccaf199f 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -199,6 +199,43 @@ interrupts = <25 4>; status = "disabled"; }; + + adc0: adc@fffb0000 { + compatible = "atmel,at91sam9260-adc"; + reg = <0xfffb0000 0x100>; + interrupts = <20 4>; + atmel,adc-use-external-triggers; + atmel,adc-channels-used = <0xff>; + atmel,adc-vref = <3300>; + atmel,adc-num-channels = <8>; + atmel,adc-startup-time = <40>; + atmel,adc-channel-base = <0x30>; + atmel,adc-drdy-mask = <0x10000>; + atmel,adc-status-register = <0x1c>; + atmel,adc-trigger-register = <0x08>; + + trigger@0 { + trigger-name = "external-rising"; + trigger-value = <0x1>; + trigger-external; + }; + trigger@1 { + trigger-name = "external-falling"; + trigger-value = <0x2>; + trigger-external; + }; + + trigger@2 { + trigger-name = "external-any"; + trigger-value = <0x3>; + trigger-external; + }; + + trigger@3 { + trigger-name = "continuous"; + trigger-value = <0x6>; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index dd4ed748469..6b3ef4339ae 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -190,6 +190,44 @@ interrupts = <27 4>; status = "disabled"; }; + + adc0: adc@f804c000 { + compatible = "atmel,at91sam9260-adc"; + reg = <0xf804c000 0x100>; + interrupts = <19 4>; + atmel,adc-use-external; + atmel,adc-channels-used = <0xffff>; + atmel,adc-vref = <3300>; + atmel,adc-num-channels = <12>; + atmel,adc-startup-time = <40>; + atmel,adc-channel-base = <0x50>; + atmel,adc-drdy-mask = <0x1000000>; + atmel,adc-status-register = <0x30>; + atmel,adc-trigger-register = <0xc0>; + + trigger@0 { + trigger-name = "external-rising"; + trigger-value = <0x1>; + trigger-external; + }; + + trigger@1 { + trigger-name = "external-falling"; + trigger-value = <0x2>; + trigger-external; + }; + + trigger@2 { + trigger-name = "external-any"; + trigger-value = <0x3>; + trigger-external; + }; + + trigger@3 { + trigger-name = "continuous"; + trigger-value = <0x6>; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index a27bbec50ca..2b1e438ed87 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -55,6 +55,13 @@ static struct clk adc_clk = { .pmc_mask = 1 << AT91SAM9260_ID_ADC, .type = CLK_TYPE_PERIPHERAL, }; + +static struct clk adc_op_clk = { + .name = "adc_op_clk", + .type = CLK_TYPE_PERIPHERAL, + .rate_hz = 5000000, +}; + static struct clk usart0_clk = { .name = "usart0_clk", .pmc_mask = 1 << AT91SAM9260_ID_US0, @@ -166,6 +173,7 @@ static struct clk *periph_clocks[] __initdata = { &pioB_clk, &pioC_clk, &adc_clk, + &adc_op_clk, &usart0_clk, &usart1_clk, &usart2_clk, diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index d556de14111..0ded951f785 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -17,12 +17,15 @@ #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> #include <mach/at91sam9260_matrix.h> #include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> +#include <mach/at91_adc.h> #include "generic.h" @@ -1340,6 +1343,93 @@ 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 IS_ENABLED(CONFIG_AT91_ADC) +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), +}; + +static struct at91_adc_trigger at91_adc_triggers[] = { + [0] = { + .name = "timer-counter-0", + .value = AT91_ADC_TRGSEL_TC0 | AT91_ADC_TRGEN, + }, + [1] = { + .name = "timer-counter-1", + .value = AT91_ADC_TRGSEL_TC1 | AT91_ADC_TRGEN, + }, + [2] = { + .name = "timer-counter-2", + .value = AT91_ADC_TRGSEL_TC2 | AT91_ADC_TRGEN, + }, + [3] = { + .name = "external", + .value = AT91_ADC_TRGSEL_EXTERNAL | AT91_ADC_TRGEN, + .is_external = true, + }, +}; + +static struct at91_adc_reg_desc at91_adc_register_g20 = { + .channel_base = AT91_ADC_CHR(0), + .drdy_mask = AT91_ADC_DRDY, + .status_register = AT91_ADC_SR, + .trigger_register = AT91_ADC_MR, +}; + +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); + + if (data->use_external_triggers) + at91_set_A_periph(AT91_PIN_PA22, 0); + + data->num_channels = 4; + data->startup_time = 10; + data->registers = &at91_adc_register_g20; + data->trigger_number = 4; + data->trigger_list = at91_adc_triggers; + + 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 diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index f2054495a65..4792682d52b 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -176,6 +176,12 @@ static struct clk vdec_clk = { .type = CLK_TYPE_PERIPHERAL, }; +static struct clk adc_op_clk = { + .name = "adc_op_clk", + .type = CLK_TYPE_PERIPHERAL, + .rate_hz = 13200000, +}; + static struct clk *periph_clocks[] __initdata = { &pioA_clk, &pioB_clk, @@ -204,6 +210,7 @@ static struct clk *periph_clocks[] __initdata = { &isi_clk, &udphs_clk, &mmc1_clk, + &adc_op_clk, // irq0 }; @@ -242,6 +249,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("pioC", &pioC_clk), CLKDEV_CON_ID("pioD", &pioDE_clk), CLKDEV_CON_ID("pioE", &pioDE_clk), + /* Fake adc clock */ + CLKDEV_CON_ID("adc_clk", &tsc_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 35bd42d0219..f6747246d64 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -19,9 +19,12 @@ #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> +#include <mach/at91_adc.h> #include <mach/board.h> #include <mach/at91sam9g45.h> #include <mach/at91sam9g45_matrix.h> @@ -1182,6 +1185,104 @@ void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} /* -------------------------------------------------------------------- + * ADC + * -------------------------------------------------------------------- */ + +#if IS_ENABLED(CONFIG_AT91_ADC) +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), +}; + +static struct at91_adc_trigger at91_adc_triggers[] = { + [0] = { + .name = "external-rising", + .value = 1, + .is_external = true, + }, + [1] = { + .name = "external-falling", + .value = 2, + .is_external = true, + }, + [2] = { + .name = "external-any", + .value = 3, + .is_external = true, + }, + [3] = { + .name = "continuous", + .value = 6, + .is_external = false, + }, +}; + +static struct at91_adc_reg_desc at91_adc_register_g45 = { + .channel_base = AT91_ADC_CHR(0), + .drdy_mask = AT91_ADC_DRDY, + .status_register = AT91_ADC_SR, + .trigger_register = 0x08, +}; + +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); + + if (data->use_external_triggers) + at91_set_A_periph(AT91_PIN_PD28, 0); + + data->num_channels = 8; + data->startup_time = 40; + data->registers = &at91_adc_register_g45; + data->trigger_number = 4; + data->trigger_list = at91_adc_triggers; + + adc_data = *data; + platform_device_register(&at91_adc_device); +} +#else +void __init at91_add_device_adc(struct at91_adc_data *data) {} +#endif + +/* -------------------------------------------------------------------- * RTT * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index 13c8cae6046..1b144b4d3ce 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -120,6 +120,11 @@ static struct clk adc_clk = { .pmc_mask = 1 << AT91SAM9X5_ID_ADC, .type = CLK_TYPE_PERIPHERAL, }; +static struct clk adc_op_clk = { + .name = "adc_op_clk", + .type = CLK_TYPE_PERIPHERAL, + .rate_hz = 5000000, +}; static struct clk dma0_clk = { .name = "dma0_clk", .pmc_mask = 1 << AT91SAM9X5_ID_DMA0, @@ -205,6 +210,7 @@ static struct clk *periph_clocks[] __initdata = { &tcb0_clk, &pwm_clk, &adc_clk, + &adc_op_clk, &dma0_clk, &dma1_clk, &uhphs_clk, diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 3d615532ae5..6860d345110 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -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> @@ -304,6 +306,16 @@ 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), + .use_external_triggers = true, + .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"), @@ -389,6 +401,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) */ diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 9a87f0b072f..63163dc7df4 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -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> @@ -305,6 +307,14 @@ 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), + .use_external_triggers = true, + .vref = 3300, +}; /* * GPIO Buttons @@ -476,6 +486,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 */ |