|
@@ -1194,3 +1194,184 @@ static struct resource cf1_resources[] = {
|
|
|
};
|
|
|
|
|
|
static struct platform_device cf1_device = {
|
|
|
+ .id = 1,
|
|
|
+ .dev = {
|
|
|
+ .platform_data = &cf1_data,
|
|
|
+ },
|
|
|
+ .resource = cf1_resources,
|
|
|
+ .num_resources = ARRAY_SIZE(cf1_resources),
|
|
|
+};
|
|
|
+
|
|
|
+void __init at91_add_device_cf(struct at91_cf_data *data)
|
|
|
+{
|
|
|
+ struct platform_device *pdev;
|
|
|
+ unsigned long csa;
|
|
|
+
|
|
|
+ if (!data)
|
|
|
+ return;
|
|
|
+
|
|
|
+ csa = at91_matrix_read(AT91_MATRIX_EBICSA);
|
|
|
+
|
|
|
+ switch (data->chipselect) {
|
|
|
+ case 4:
|
|
|
+ at91_set_multi_drive(AT91_PIN_PC8, 0);
|
|
|
+ at91_set_A_periph(AT91_PIN_PC8, 0);
|
|
|
+ csa |= AT91_MATRIX_CS4A_SMC_CF1;
|
|
|
+ cf0_data = *data;
|
|
|
+ pdev = &cf0_device;
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ at91_set_multi_drive(AT91_PIN_PC9, 0);
|
|
|
+ at91_set_A_periph(AT91_PIN_PC9, 0);
|
|
|
+ csa |= AT91_MATRIX_CS5A_SMC_CF2;
|
|
|
+ cf1_data = *data;
|
|
|
+ pdev = &cf1_device;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
|
|
|
+ data->chipselect);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ at91_matrix_write(AT91_MATRIX_EBICSA, csa);
|
|
|
+
|
|
|
+ if (gpio_is_valid(data->rst_pin)) {
|
|
|
+ at91_set_multi_drive(data->rst_pin, 0);
|
|
|
+ at91_set_gpio_output(data->rst_pin, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (gpio_is_valid(data->irq_pin)) {
|
|
|
+ at91_set_gpio_input(data->irq_pin, 0);
|
|
|
+ at91_set_deglitch(data->irq_pin, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (gpio_is_valid(data->det_pin)) {
|
|
|
+ at91_set_gpio_input(data->det_pin, 0);
|
|
|
+ at91_set_deglitch(data->det_pin, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ at91_set_B_periph(AT91_PIN_PC6, 0); /* CFCE1 */
|
|
|
+ at91_set_B_periph(AT91_PIN_PC7, 0); /* CFCE2 */
|
|
|
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* CFRNW */
|
|
|
+ at91_set_A_periph(AT91_PIN_PC15, 1); /* NWAIT */
|
|
|
+
|
|
|
+ if (data->flags & AT91_CF_TRUE_IDE)
|
|
|
+#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
|
|
|
+ pdev->name = "pata_at91";
|
|
|
+#else
|
|
|
+#warning "board requires AT91_CF_TRUE_IDE: enable pata_at91"
|
|
|
+#endif
|
|
|
+ else
|
|
|
+ pdev->name = "at91_cf";
|
|
|
+
|
|
|
+ platform_device_register(pdev);
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+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 = NR_IRQS_LEGACY + AT91SAM9260_ID_ADC,
|
|
|
+ .end = NR_IRQS_LEGACY + 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
|
|
|
+ * setup.
|
|
|
+ */
|
|
|
+static int __init at91_add_standard_devices(void)
|
|
|
+{
|
|
|
+ if (of_have_populated_dt())
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ at91_add_device_rtt();
|
|
|
+ at91_add_device_watchdog();
|
|
|
+ at91_add_device_tc();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+arch_initcall(at91_add_standard_devices);
|