Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13b9d47e authored by Richard Purdie's avatar Richard Purdie Committed by Russell King
Browse files

[ARM] 2914/1: PXA Poodle: Add MMC and UDC support



Patch from Richard Purdie

This patch adds MMC and UDC support to the PXA Poodle platform.

Signed-off-by: default avatarRichard Purdie <rpurdie@rpsys.net>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent f29d2455
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@

#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/poodle.h>
#include <asm/arch/pxafb.h>

@@ -93,6 +95,83 @@ static struct platform_device locomo_device = {
	.resource	= locomo_resources,
};


/*
 * MMC/SD Device
 *
 * The card detect interrupt isn't debounced so we delay it by 250ms
 * to give the card a chance to fully insert/eject.
 */
static struct pxamci_platform_data poodle_mci_platform_data;

static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)(int, void *, struct pt_regs *), void *data)
{
	int err;

	/* setup GPIO for PXA25x MMC controller	*/
	pxa_gpio_mode(GPIO6_MMCCLK_MD);
	pxa_gpio_mode(GPIO8_MMCCS0_MD);
	pxa_gpio_mode(POODLE_GPIO_nSD_DETECT | GPIO_IN);
	pxa_gpio_mode(POODLE_GPIO_SD_PWR | GPIO_OUT);

	poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);

	err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, SA_INTERRUPT,
			     "MMC card detect", data);
	if (err) {
		printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
		return -1;
	}

	set_irq_type(POODLE_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);

	return 0;
}

static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
{
	struct pxamci_platform_data* p_d = dev->platform_data;

	if (( 1 << vdd) & p_d->ocr_mask)
		GPSR1 = GPIO_bit(POODLE_GPIO_SD_PWR);
	else
		GPCR1 = GPIO_bit(POODLE_GPIO_SD_PWR);
}

static void poodle_mci_exit(struct device *dev, void *data)
{
	free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data);
}

static struct pxamci_platform_data poodle_mci_platform_data = {
	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
	.init 		= poodle_mci_init,
	.setpower 	= poodle_mci_setpower,
	.exit		= poodle_mci_exit,
};


/*
 * USB Device Controller
 */
static void poodle_udc_command(int cmd)
{
	switch(cmd)	{
	case PXA2XX_UDC_CMD_CONNECT:
		GPSR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP);
		break;
	case PXA2XX_UDC_CMD_DISCONNECT:
		GPCR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP);
		break;
	}
}

static struct pxa2xx_udc_mach_info udc_info __initdata = {
	/* no connect GPIO; poodle can't tell connection status */
	.udc_command		= poodle_udc_command,
};


/* PXAFB device */
static struct pxafb_mach_info poodle_fb_info __initdata = {
	.pixclock	= 144700,
@@ -164,6 +243,9 @@ static void __init poodle_init(void)
        GPSR2 = 0x00000000;

	set_pxa_fb_info(&poodle_fb_info);
	pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
	pxa_set_udc_info(&udc_info);
	pxa_set_mci_info(&poodle_mci_platform_data);

	scoop_num = 1;
	scoop_devs = &poodle_pcmcia_scoop[0];