Commit 15893fb5 authored by Paul Mundt's avatar Paul Mundt

Merge branch 'sh/sdhi-mfd'

Conflicts:
	arch/sh/boards/mach-ecovec24/setup.c
	arch/sh/boards/mach-kfr2r09/setup.c
parents f32154c9 96987d96
......@@ -20,8 +20,6 @@
#include <linux/i2c.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <media/ov772x.h>
#include <media/soc_camera.h>
#include <media/soc_camera_platform.h>
......@@ -409,17 +407,25 @@ static struct platform_device ceu_device = {
},
};
struct spi_gpio_platform_data sdcard_cn3_platform_data = {
.sck = GPIO_PTD0,
.mosi = GPIO_PTD1,
.miso = GPIO_PTD2,
.num_chipselect = 1,
static struct resource sdhi0_cn3_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
.end = 0x04ce01ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 101,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sdcard_cn3_device = {
.name = "spi_gpio",
.dev = {
.platform_data = &sdcard_cn3_platform_data,
static struct platform_device sdhi0_cn3_device = {
.name = "sh_mobile_sdhi",
.num_resources = ARRAY_SIZE(sdhi0_cn3_resources),
.resource = sdhi0_cn3_resources,
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
};
......@@ -470,20 +476,11 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
&lcdc_device,
&ceu_device,
&nand_flash_device,
&sdcard_cn3_device,
&sdhi0_cn3_device,
&ap325rxa_camera[0],
&ap325rxa_camera[1],
};
static struct spi_board_info ap325rxa_spi_devices[] = {
{
.modalias = "mmc_spi",
.max_speed_hz = 5000000,
.chip_select = 0,
.controller_data = (void *) GPIO_PTD5,
},
};
static int __init ap325rxa_devices_setup(void)
{
/* LD3 and LD4 LEDs */
......@@ -578,12 +575,19 @@ static int __init ap325rxa_devices_setup(void)
platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
/* SDHI0 */
gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
i2c_register_board_info(0, ap325rxa_i2c_devices,
ARRAY_SIZE(ap325rxa_i2c_devices));
spi_register_board_info(ap325rxa_spi_devices,
ARRAY_SIZE(ap325rxa_spi_devices));
return platform_add_devices(ap325rxa_devices,
ARRAY_SIZE(ap325rxa_devices));
}
......
......@@ -428,6 +428,54 @@ static struct i2c_board_info ts_i2c_clients = {
.irq = IRQ0,
};
/* SHDI0 */
static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
.end = 0x04ce01ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 101,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sdhi0_device = {
.name = "sh_mobile_sdhi",
.num_resources = ARRAY_SIZE(sdhi0_resources),
.resource = sdhi0_resources,
.id = 0,
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
};
/* SHDI1 */
static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0x04cf0000,
.end = 0x04cf01ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 24,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sdhi1_device = {
.name = "sh_mobile_sdhi",
.num_resources = ARRAY_SIZE(sdhi1_resources),
.resource = sdhi1_resources,
.id = 1,
.archdata = {
.hwblk_id = HWBLK_SDHI1,
},
};
static struct platform_device *ecovec_devices[] __initdata = {
&heartbeat_device,
&nor_flash_device,
......@@ -438,6 +486,8 @@ static struct platform_device *ecovec_devices[] __initdata = {
&ceu0_device,
&ceu1_device,
&keysc_device,
&sdhi0_device,
&sdhi1_device,
};
#define EEPROM_ADDR 0x50
......@@ -710,6 +760,34 @@ static int __init arch_setup(void)
gpio_direction_input(GPIO_PTR5);
gpio_direction_input(GPIO_PTR6);
/* enable SDHI0 */
gpio_request(GPIO_FN_SDHI0CD, NULL);
gpio_request(GPIO_FN_SDHI0WP, NULL);
gpio_request(GPIO_FN_SDHI0CMD, NULL);
gpio_request(GPIO_FN_SDHI0CLK, NULL);
gpio_request(GPIO_FN_SDHI0D3, NULL);
gpio_request(GPIO_FN_SDHI0D2, NULL);
gpio_request(GPIO_FN_SDHI0D1, NULL);
gpio_request(GPIO_FN_SDHI0D0, NULL);
/* enable SDHI1 */
gpio_request(GPIO_FN_SDHI1CD, NULL);
gpio_request(GPIO_FN_SDHI1WP, NULL);
gpio_request(GPIO_FN_SDHI1CMD, NULL);
gpio_request(GPIO_FN_SDHI1CLK, NULL);
gpio_request(GPIO_FN_SDHI1D3, NULL);
gpio_request(GPIO_FN_SDHI1D2, NULL);
gpio_request(GPIO_FN_SDHI1D1, NULL);
gpio_request(GPIO_FN_SDHI1D0, NULL);
gpio_request(GPIO_PTB6, NULL);
gpio_request(GPIO_PTB7, NULL);
gpio_direction_output(GPIO_PTB6, 1);
gpio_direction_output(GPIO_PTB7, 1);
/* I/O buffer drive ability is high for SDHI1 */
ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
/* enable I2C device */
i2c_register_board_info(1, i2c1_devices,
ARRAY_SIZE(i2c1_devices));
......@@ -726,7 +804,6 @@ static int __init devices_setup(void)
}
device_initcall(devices_setup);
static struct sh_machine_vector mv_ecovec __initmv = {
.mv_name = "R0P7724 (EcoVec)",
};
......@@ -332,6 +332,28 @@ static struct platform_device kfr2r09_camera = {
},
};
static struct resource kfr2r09_sh_sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
.end = 0x04ce01ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 101,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device kfr2r09_sh_sdhi0_device = {
.name = "sh_mobile_sdhi",
.num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources),
.resource = kfr2r09_sh_sdhi0_resources,
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
};
static struct platform_device *kfr2r09_devices[] __initdata = {
&kfr2r09_nor_flash_device,
&kfr2r09_nand_flash_device,
......@@ -339,6 +361,7 @@ static struct platform_device *kfr2r09_devices[] __initdata = {
&kfr2r09_sh_lcdc_device,
&kfr2r09_ceu_device,
&kfr2r09_camera,
&kfr2r09_sh_sdhi0_device,
};
#define BSC_CS0BCR 0xfec10004
......@@ -500,6 +523,16 @@ static int __init kfr2r09_devices_setup(void)
platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20);
/* SDHI0 connected to yc304 */
gpio_request(GPIO_FN_SDHI0CD, NULL);
gpio_request(GPIO_FN_SDHI0WP, NULL);
gpio_request(GPIO_FN_SDHI0D3, NULL);
gpio_request(GPIO_FN_SDHI0D2, NULL);
gpio_request(GPIO_FN_SDHI0D1, NULL);
gpio_request(GPIO_FN_SDHI0D0, NULL);
gpio_request(GPIO_FN_SDHI0CMD, NULL);
gpio_request(GPIO_FN_SDHI0CLK, NULL);
return platform_add_devices(kfr2r09_devices,
ARRAY_SIZE(kfr2r09_devices));
}
......
......@@ -18,8 +18,6 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <video/sh_mobile_lcdc.h>
#include <media/sh_mobile_ceu.h>
#include <media/ov772x.h>
......@@ -390,17 +388,25 @@ static struct platform_device migor_ceu_device = {
},
};
struct spi_gpio_platform_data sdcard_cn9_platform_data = {
.sck = GPIO_PTD0,
.mosi = GPIO_PTD1,
.miso = GPIO_PTD2,
.num_chipselect = 1,
static struct resource sdhi_cn9_resources[] = {
[0] = {
.name = "SDHI",
.start = 0x04ce0000,
.end = 0x04ce01ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 101,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sdcard_cn9_device = {
.name = "spi_gpio",
.dev = {
.platform_data = &sdcard_cn9_platform_data,
static struct platform_device sdhi_cn9_device = {
.name = "sh_mobile_sdhi",
.num_resources = ARRAY_SIZE(sdhi_cn9_resources),
.resource = sdhi_cn9_resources,
.archdata = {
.hwblk_id = HWBLK_SDHI,
},
};
......@@ -467,20 +473,11 @@ static struct platform_device *migor_devices[] __initdata = {
&migor_ceu_device,
&migor_nor_flash_device,
&migor_nand_flash_device,
&sdcard_cn9_device,
&sdhi_cn9_device,
&migor_camera[0],
&migor_camera[1],
};
static struct spi_board_info migor_spi_devices[] = {
{
.modalias = "mmc_spi",
.max_speed_hz = 5000000,
.chip_select = 0,
.controller_data = (void *) GPIO_PTD5,
},
};
static int __init migor_devices_setup(void)
{
......@@ -525,6 +522,16 @@ static int __init migor_devices_setup(void)
gpio_request(GPIO_PTA1, NULL);
gpio_direction_input(GPIO_PTA1);
/* SDHI */
gpio_request(GPIO_FN_SDHICD, NULL);
gpio_request(GPIO_FN_SDHIWP, NULL);
gpio_request(GPIO_FN_SDHID3, NULL);
gpio_request(GPIO_FN_SDHID2, NULL);
gpio_request(GPIO_FN_SDHID1, NULL);
gpio_request(GPIO_FN_SDHID0, NULL);
gpio_request(GPIO_FN_SDHICMD, NULL);
gpio_request(GPIO_FN_SDHICLK, NULL);
/* Touch Panel */
gpio_request(GPIO_FN_IRQ6, NULL);
......@@ -612,9 +619,6 @@ static int __init migor_devices_setup(void)
i2c_register_board_info(0, migor_i2c_devices,
ARRAY_SIZE(migor_i2c_devices));
spi_register_board_info(migor_spi_devices,
ARRAY_SIZE(migor_spi_devices));
return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
}
arch_initcall(migor_devices_setup);
......
......@@ -448,6 +448,28 @@ static struct platform_device sh7724_usb1_gadget_device = {
.resource = sh7724_usb1_gadget_resources,
};
static struct resource sdhi0_cn7_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
.end = 0x04ce01ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 101,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sdhi0_cn7_device = {
.name = "sh_mobile_sdhi",
.num_resources = ARRAY_SIZE(sdhi0_cn7_resources),
.resource = sdhi0_cn7_resources,
.archdata = {
.hwblk_id = HWBLK_SDHI0,
},
};
static struct platform_device *ms7724se_devices[] __initdata = {
&heartbeat_device,
&smc91x_eth_device,
......@@ -460,6 +482,7 @@ static struct platform_device *ms7724se_devices[] __initdata = {
&sh7724_usb0_host_device,
&sh7724_usb1_gadget_device,
&fsi_device,
&sdhi0_cn7_device,
};
#define EEPROM_OP 0xBA206000
......@@ -698,6 +721,16 @@ static int __init devices_setup(void)
clk_set_rate(&fsimcka_clk, 11000);
clk_put(fsia_clk);
/* SDHI0 connected to cn7 */
gpio_request(GPIO_FN_SDHI0CD, NULL);
gpio_request(GPIO_FN_SDHI0WP, NULL);
gpio_request(GPIO_FN_SDHI0D3, NULL);
gpio_request(GPIO_FN_SDHI0D2, NULL);
gpio_request(GPIO_FN_SDHI0D1, NULL);
gpio_request(GPIO_FN_SDHI0D0, NULL);
gpio_request(GPIO_FN_SDHI0CMD, NULL);
gpio_request(GPIO_FN_SDHI0CLK, NULL);
/*
* enable SH-Eth
*
......
......@@ -35,6 +35,14 @@ config MFD_ASIC3
This driver supports the ASIC3 multifunction chip found on many
PDAs (mainly iPAQ and HTC based ones)
config MFD_SH_MOBILE_SDHI
bool "Support for SuperH Mobile SDHI"
depends on SUPERH
select MFD_CORE
---help---
This driver supports the SDHI hardware block found in many
SuperH Mobile SoCs.
config MFD_DM355EVM_MSP
bool "DaVinci DM355 EVM microcontroller"
depends on I2C && MACH_DAVINCI_DM355_EVM
......
......@@ -4,6 +4,7 @@
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o
obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
......
/*
* SuperH Mobile SDHI
*
* Copyright (C) 2009 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Based on "Compaq ASIC3 support":
*
* Copyright 2001 Compaq Computer Corporation.
* Copyright 2004-2005 Phil Blundell
* Copyright 2007-2008 OpenedHand Ltd.
*
* Authors: Phil Blundell <pb@handhelds.org>,
* Samuel Ortiz <sameo@openedhand.com>
*
*/
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tmio.h>
struct sh_mobile_sdhi {
struct clk *clk;
struct tmio_mmc_data mmc_data;
struct mfd_cell cell_mmc;
};
static struct resource sh_mobile_sdhi_resources[] = {
{
.start = 0x000,
.end = 0x1ff,
.flags = IORESOURCE_MEM,
},
{
.start = 0,
.end = 0,
.flags = IORESOURCE_IRQ,
},
};
static struct mfd_cell sh_mobile_sdhi_cell = {
.name = "tmio-mmc",
.num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
.resources = sh_mobile_sdhi_resources,
};
static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
{
struct sh_mobile_sdhi *priv;
struct resource *mem;
char clk_name[8];
int ret, irq;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem)
dev_err(&pdev->dev, "missing MEM resource\n");
irq = platform_get_irq(pdev, 0);
if (irq < 0)
dev_err(&pdev->dev, "missing IRQ resource\n");
if (!mem || (irq < 0))
return -EINVAL;
priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
if (priv == NULL) {
dev_err(&pdev->dev, "kzalloc failed\n");
return -ENOMEM;
}
snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
priv->clk = clk_get(&pdev->dev, clk_name);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
ret = PTR_ERR(priv->clk);
kfree(priv);
return ret;
}
clk_enable(priv->clk);
/* FIXME: silly const unsigned int hclk */
*(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
priv->cell_mmc.driver_data = &priv->mmc_data;
priv->cell_mmc.platform_data = &priv->cell_mmc;
priv->cell_mmc.data_size = sizeof(priv->cell_mmc);
platform_set_drvdata(pdev, priv);
ret = mfd_add_devices(&pdev->dev, pdev->id,
&priv->cell_mmc, 1, mem, irq);
if (ret) {
clk_disable(priv->clk);
clk_put(priv->clk);
kfree(priv);
}
return ret;
}
static int sh_mobile_sdhi_remove(struct platform_device *pdev)
{
struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);
mfd_remove_devices(&pdev->dev);
clk_disable(priv->clk);
clk_put(priv->clk);
kfree(priv);
return 0;
}
static struct platform_driver sh_mobile_sdhi_driver = {
.driver = {
.name = "sh_mobile_sdhi",
.owner = THIS_MODULE,
},
.probe = sh_mobile_sdhi_probe,
.remove = __devexit_p(sh_mobile_sdhi_remove),
};
static int __init sh_mobile_sdhi_init(void)
{
return platform_driver_register(&sh_mobile_sdhi_driver);
}
static void __exit sh_mobile_sdhi_exit(void)
{
platform_driver_unregister(&sh_mobile_sdhi_driver);
}
module_init(sh_mobile_sdhi_init);
module_exit(sh_mobile_sdhi_exit);
MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL v2");
......@@ -329,7 +329,7 @@ config MMC_SDRICOH_CS
config MMC_TMIO
tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
depends on MFD_TMIO || MFD_ASIC3
depends on MFD_TMIO || MFD_ASIC3 || SUPERH
help
This provides support for the SD/MMC cell found in TC6393XB,
T7L66XB and also HTC ASIC3
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment