Browse Source

waterHeterogeneousDataSynchronization commandProcessing.c 李欣儒 commit at 2021-01-11

李欣儒 4 years ago
parent
commit
7fb88c86f8

+ 125 - 0
waterHeterogeneousDataSynchronization/externalConnectionMonitoring/commandProcessing.c

@@ -1412,3 +1412,128 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
 	case 0:
 		/* Slot is unused */
 		break;
+	default:
+		if (!data->slot[0].bus_width)
+			goto fail_free;
+
+		data->slot[1].bus_width = 0;
+		break;
+	}
+
+	atmel_mci0_pclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+	return pdev;
+
+fail_free:
+	kfree(slave);
+fail:
+	data->dma_slave = NULL;
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ *  LCDC
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
+static struct atmel_lcdfb_info atmel_lcdfb0_data;
+static struct resource atmel_lcdfb0_resource[] = {
+	{
+		.start		= 0xff000000,
+		.end		= 0xff000fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	IRQ(1),
+	{
+		/* Placeholder for pre-allocated fb memory */
+		.start		= 0x00000000,
+		.end		= 0x00000000,
+		.flags		= 0,
+	},
+};
+DEFINE_DEV_DATA(atmel_lcdfb, 0);
+DEV_CLK(hck1, atmel_lcdfb0, hsb, 7);
+static struct clk atmel_lcdfb0_pixclk = {
+	.name		= "lcdc_clk",
+	.dev		= &atmel_lcdfb0_device.dev,
+	.mode		= genclk_mode,
+	.get_rate	= genclk_get_rate,
+	.set_rate	= genclk_set_rate,
+	.set_parent	= genclk_set_parent,
+	.index		= 7,
+};
+
+struct platform_device *__init
+at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
+		     unsigned long fbmem_start, unsigned long fbmem_len,
+		     u64 pin_mask)
+{
+	struct platform_device *pdev;
+	struct atmel_lcdfb_info *info;
+	struct fb_monspecs *monspecs;
+	struct fb_videomode *modedb;
+	unsigned int modedb_size;
+	u32 portc_mask, portd_mask, porte_mask;
+
+	/*
+	 * Do a deep copy of the fb data, monspecs and modedb. Make
+	 * sure all allocations are done before setting up the
+	 * portmux.
+	 */
+	monspecs = kmemdup(data->default_monspecs,
+			   sizeof(struct fb_monspecs), GFP_KERNEL);
+	if (!monspecs)
+		return NULL;
+
+	modedb_size = sizeof(struct fb_videomode) * monspecs->modedb_len;
+	modedb = kmemdup(monspecs->modedb, modedb_size, GFP_KERNEL);
+	if (!modedb)
+		goto err_dup_modedb;
+	monspecs->modedb = modedb;
+
+	switch (id) {
+	case 0:
+		pdev = &atmel_lcdfb0_device;
+
+		if (pin_mask == 0ULL)
+			/* Default to "full" lcdc control signals and 24bit */
+			pin_mask = ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL;
+
+		/* LCDC on port C */
+		portc_mask = pin_mask & 0xfff80000;
+		select_peripheral(PIOC, portc_mask, PERIPH_A, 0);
+
+		/* LCDC on port D */
+		portd_mask = pin_mask & 0x0003ffff;
+		select_peripheral(PIOD, portd_mask, PERIPH_A, 0);
+
+		/* LCDC on port E */
+		porte_mask = (pin_mask >> 32) & 0x0007ffff;
+		select_peripheral(PIOE, porte_mask, PERIPH_B, 0);
+
+		clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
+		clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
+		break;
+
+	default:
+		goto err_invalid_id;
+	}
+
+	if (fbmem_len) {
+		pdev->resource[2].start = fbmem_start;
+		pdev->resource[2].end = fbmem_start + fbmem_len - 1;
+		pdev->resource[2].flags = IORESOURCE_MEM;
+	}
+
+	info = pdev->dev.platform_data;
+	memcpy(info, data, sizeof(struct atmel_lcdfb_info));
+	info->default_monspecs = monspecs;
+
+	platform_device_register(pdev);
+	return pdev;
+
+err_invalid_id:
+	kfree(modedb);
+err_dup_modedb:
+	kfree(monspecs);