All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] ASIC3 updates (v2)
@ 2009-06-05 16:31 Philipp Zabel
  2009-06-05 16:31 ` [PATCH 1/7] MFD: ASIC3: add asic3_set_register common operation Philipp Zabel
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz

Hi,

second try. I've merged the new functions in patch 1 into asic3_set_register
and updated the following patches accordingly.

regards
Philipp

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/7] MFD: ASIC3: add asic3_set_register common operation
  2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
@ 2009-06-05 16:31 ` Philipp Zabel
  2009-06-05 16:31 ` [PATCH 2/7] MFD: ASIC3: add clock handling for MFD cells Philipp Zabel
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

Used to configure single bits of the SDHWCTRL_SDCONF and EXTCF_RESET/SELECT
registers needed for DS1WM, MMC/SDIO and PCMCIA functionality.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 drivers/mfd/asic3.c       |   15 +++++++++++++++
 include/linux/mfd/asic3.h |   10 +++++-----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 9e48545..ad3c591 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -52,6 +52,21 @@ static inline u32 asic3_read_register(struct asic3 *asic,
 			(reg >> asic->bus_shift));
 }
 
+void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&asic->lock, flags);
+	val = asic3_read_register(asic, reg);
+	if (set)
+		val |= bits;
+	else
+		val &= ~bits;
+	asic3_write_register(asic, reg, val);
+	spin_unlock_irqrestore(&asic->lock, flags);
+}
+
 /* IRQs */
 #define MAX_ASIC_ISR_LOOPS    20
 #define ASIC3_GPIO_BASE_INCR \
diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h
index 322cd6d..6b427ec 100644
--- a/include/linux/mfd/asic3.h
+++ b/include/linux/mfd/asic3.h
@@ -227,8 +227,8 @@ struct asic3_platform_data {
 
 
 /* Basic control of the SD ASIC */
-#define ASIC3_SDHWCTRL_Base	0x0E00
-#define ASIC3_SDHWCTRL_SDConf    0x00
+#define ASIC3_SDHWCTRL_BASE     0x0E00
+#define ASIC3_SDHWCTRL_SDCONF     0x00
 
 #define ASIC3_SDHWCTRL_SUSPEND    (1 << 0)  /* 1=suspend all SD operations */
 #define ASIC3_SDHWCTRL_CLKSEL     (1 << 1)  /* 1=SDICK, 0=HCLK */
@@ -242,10 +242,10 @@ struct asic3_platform_data {
 /* SD card power supply ctrl 1=enable */
 #define ASIC3_SDHWCTRL_SDPWR      (1 << 6)
 
-#define ASIC3_EXTCF_Base		0x1100
+#define ASIC3_EXTCF_BASE        0x1100
 
-#define ASIC3_EXTCF_Select         0x00
-#define ASIC3_EXTCF_Reset          0x04
+#define ASIC3_EXTCF_SELECT        0x00
+#define ASIC3_EXTCF_RESET         0x04
 
 #define ASIC3_EXTCF_SMOD0	         (1 << 0)  /* slot number of mode 0 */
 #define ASIC3_EXTCF_SMOD1	         (1 << 1)  /* slot number of mode 1 */
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/7] MFD: ASIC3: add clock handling for MFD cells
  2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
  2009-06-05 16:31 ` [PATCH 1/7] MFD: ASIC3: add asic3_set_register common operation Philipp Zabel
@ 2009-06-05 16:31 ` Philipp Zabel
  2009-06-05 16:31 ` [PATCH 3/7] MFD: ASIC3: add ASIC3 IRQ numbers Philipp Zabel
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

Since ASIC3 has to work on both PXA and S3C and since their
struct clk implementations differ, we can't register out
clocks with the clkdev mechanism (yet?).
For now we have to keep clock handling internal to this
driver and enable/disable the clocks via the
mfd_cell->enable/disable functions.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 drivers/mfd/asic3.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index ad3c591..ebe8893 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -25,6 +25,48 @@
 
 #include <linux/mfd/asic3.h>
 
+enum {
+	ASIC3_CLOCK_SPI,
+	ASIC3_CLOCK_OWM,
+	ASIC3_CLOCK_PWM0,
+	ASIC3_CLOCK_PWM1,
+	ASIC3_CLOCK_LED0,
+	ASIC3_CLOCK_LED1,
+	ASIC3_CLOCK_LED2,
+	ASIC3_CLOCK_SD_HOST,
+	ASIC3_CLOCK_SD_BUS,
+	ASIC3_CLOCK_SMBUS,
+	ASIC3_CLOCK_EX0,
+	ASIC3_CLOCK_EX1,
+};
+
+struct asic3_clk {
+	int enabled;
+	unsigned int cdex;
+	unsigned long rate;
+};
+
+#define INIT_CDEX(_name, _rate)	\
+	[ASIC3_CLOCK_##_name] = {		\
+		.cdex = CLOCK_CDEX_##_name,	\
+		.rate = _rate,			\
+	}
+
+struct asic3_clk asic3_clk_init[] __initdata = {
+	INIT_CDEX(SPI, 0),
+	INIT_CDEX(OWM, 5000000),
+	INIT_CDEX(PWM0, 0),
+	INIT_CDEX(PWM1, 0),
+	INIT_CDEX(LED0, 0),
+	INIT_CDEX(LED1, 0),
+	INIT_CDEX(LED2, 0),
+	INIT_CDEX(SD_HOST, 24576000),
+	INIT_CDEX(SD_BUS, 12288000),
+	INIT_CDEX(SMBUS, 0),
+	INIT_CDEX(EX0, 32768),
+	INIT_CDEX(EX1, 24576000),
+};
+
 struct asic3 {
 	void __iomem *mapping;
 	unsigned int bus_shift;
@@ -34,6 +76,8 @@ struct asic3 {
 	u16 irq_bothedge[4];
 	struct gpio_chip gpio;
 	struct device *dev;
+
+	struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)];
 };
 
 static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset);
@@ -540,6 +584,37 @@ static int asic3_gpio_remove(struct platform_device *pdev)
 	return gpiochip_remove(&asic->gpio);
 }
 
+static int asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
+{
+	unsigned long flags;
+	u32 cdex;
+
+	spin_lock_irqsave(&asic->lock, flags);
+	if (clk->enabled++ == 0) {
+		cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX));
+		cdex |= clk->cdex;
+		asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex);
+	}
+	spin_unlock_irqrestore(&asic->lock, flags);
+
+	return 0;
+}
+
+static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
+{
+	unsigned long flags;
+	u32 cdex;
+
+	WARN_ON(clk->enabled == 0);
+
+	spin_lock_irqsave(&asic->lock, flags);
+	if (--clk->enabled == 0) {
+		cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX));
+		cdex &= ~clk->cdex;
+		asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex);
+	}
+	spin_unlock_irqrestore(&asic->lock, flags);
+}
 
 /* Core */
 static int __init asic3_probe(struct platform_device *pdev)
@@ -605,6 +680,11 @@ static int __init asic3_probe(struct platform_device *pdev)
 		goto out_irq;
 	}
 
+	/* Making a per-device copy is only needed for the
+	 * theoretical case of multiple ASIC3s on one board:
+	 */
+	memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init));
+
 	dev_info(asic->dev, "ASIC3 Core driver\n");
 
 	return 0;
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/7] MFD: ASIC3: add ASIC3 IRQ numbers
  2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
  2009-06-05 16:31 ` [PATCH 1/7] MFD: ASIC3: add asic3_set_register common operation Philipp Zabel
  2009-06-05 16:31 ` [PATCH 2/7] MFD: ASIC3: add clock handling for MFD cells Philipp Zabel
@ 2009-06-05 16:31 ` Philipp Zabel
  2009-06-05 16:31 ` [PATCH 4/7] MFD: ASIC3: use resource_size macro instead of local variable Philipp Zabel
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

IRQ number definitions for PWM, LED, SPI and OWM (ds1wm).

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 include/linux/mfd/asic3.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h
index 6b427ec..d2ecaaf 100644
--- a/include/linux/mfd/asic3.h
+++ b/include/linux/mfd/asic3.h
@@ -30,6 +30,13 @@ struct asic3_platform_data {
 #define ASIC3_NUM_GPIOS		64
 #define ASIC3_NR_IRQS		ASIC3_NUM_GPIOS + 6
 
+#define ASIC3_IRQ_LED0		64
+#define ASIC3_IRQ_LED1		65
+#define ASIC3_IRQ_LED2		66
+#define ASIC3_IRQ_SPI		67
+#define ASIC3_IRQ_SMBUS		68
+#define ASIC3_IRQ_OWM		69
+
 #define ASIC3_TO_GPIO(gpio) (NR_BUILTIN_GPIO + (gpio))
 
 #define ASIC3_GPIO_BANK_A	0
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/7] MFD: ASIC3: use resource_size macro instead of local variable
  2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
                   ` (2 preceding siblings ...)
  2009-06-05 16:31 ` [PATCH 3/7] MFD: ASIC3: add ASIC3 IRQ numbers Philipp Zabel
@ 2009-06-05 16:31 ` Philipp Zabel
  2009-06-05 16:31 ` [PATCH 5/7] MFD: ASIC3: remove SD/SDIO controller register definitions Philipp Zabel
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

This should make the code a little bit easier to read.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 drivers/mfd/asic3.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index ebe8893..d5dd0df 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -623,7 +623,6 @@ static int __init asic3_probe(struct platform_device *pdev)
 	struct asic3 *asic;
 	struct resource *mem;
 	unsigned long clksel;
-	int map_size;
 	int ret = 0;
 
 	asic = kzalloc(sizeof(struct asic3), GFP_KERNEL);
@@ -643,8 +642,7 @@ static int __init asic3_probe(struct platform_device *pdev)
 		goto out_free;
 	}
 
-	map_size = mem->end - mem->start + 1;
-	asic->mapping = ioremap(mem->start, map_size);
+	asic->mapping = ioremap(mem->start, resource_size(mem));
 	if (!asic->mapping) {
 		ret = -ENOMEM;
 		dev_err(asic->dev, "Couldn't ioremap\n");
@@ -654,7 +652,7 @@ static int __init asic3_probe(struct platform_device *pdev)
 	asic->irq_base = pdata->irq_base;
 
 	/* calculate bus shift from mem resource */
-	asic->bus_shift = 2 - (map_size >> 12);
+	asic->bus_shift = 2 - (resource_size(mem) >> 12);
 
 	clksel = 0;
 	asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), clksel);
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/7] MFD: ASIC3: remove SD/SDIO controller register definitions
  2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
                   ` (3 preceding siblings ...)
  2009-06-05 16:31 ` [PATCH 4/7] MFD: ASIC3: use resource_size macro instead of local variable Philipp Zabel
@ 2009-06-05 16:31 ` Philipp Zabel
  2009-06-05 16:31 ` [PATCH 6/7] MFD: ASIC3: enable DS1WM cell Philipp Zabel
  2009-06-05 16:31 ` [PATCH 7/7] MFD: ASIC3: enable SD/SDIO cell Philipp Zabel
  6 siblings, 0 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

Only the base addresses remain, as they are needed to set up
the IOMEM resources.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 include/linux/mfd/asic3.h |  219 +--------------------------------------------
 1 files changed, 3 insertions(+), 216 deletions(-)

diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h
index d2ecaaf..de3c4ad 100644
--- a/include/linux/mfd/asic3.h
+++ b/include/linux/mfd/asic3.h
@@ -286,222 +286,9 @@ struct asic3_platform_data {
  *  SDIO_CTRL         Control registers for SDIO operations
  *
  *****************************************************************************/
-#define ASIC3_SD_CONFIG_Base            0x0400 /* Assumes 32 bit addressing */
-
-#define ASIC3_SD_CONFIG_Command           0x08   /* R/W: Command */
-
-/* [0:8] SD Control Register Base Address */
-#define ASIC3_SD_CONFIG_Addr0             0x20
-
-/* [9:31] SD Control Register Base Address */
-#define ASIC3_SD_CONFIG_Addr1             0x24
-
-/* R/O: interrupt assigned to pin */
-#define ASIC3_SD_CONFIG_IntPin            0x78
-
-/*
- * Set to 0x1f to clock SD controller, 0 otherwise.
- * At 0x82 - Gated Clock Ctrl
- */
-#define ASIC3_SD_CONFIG_ClkStop           0x80
-
-/* Control clock of SD controller */
-#define ASIC3_SD_CONFIG_ClockMode         0x84
-#define ASIC3_SD_CONFIG_SDHC_PinStatus    0x88   /* R/0: SD pins status */
-#define ASIC3_SD_CONFIG_SDHC_Power1       0x90   /* Power1 - manual pwr ctrl */
-
-/* auto power up after card inserted */
-#define ASIC3_SD_CONFIG_SDHC_Power2       0x92
-
-/* auto power down when card removed */
-#define ASIC3_SD_CONFIG_SDHC_Power3       0x94
-#define ASIC3_SD_CONFIG_SDHC_CardDetect   0x98
-#define ASIC3_SD_CONFIG_SDHC_Slot         0xA0   /* R/O: support slot number */
-#define ASIC3_SD_CONFIG_SDHC_ExtGateClk1  0x1E0  /* Not used */
-#define ASIC3_SD_CONFIG_SDHC_ExtGateClk2  0x1E2  /* Not used*/
-
-/* GPIO Output Reg. , at 0x1EA - GPIO Output Enable Reg. */
-#define ASIC3_SD_CONFIG_SDHC_GPIO_OutAndEnable  0x1E8
-#define ASIC3_SD_CONFIG_SDHC_GPIO_Status  0x1EC  /* GPIO Status Reg. */
-
-/* Bit 1: double buffer/single buffer */
-#define ASIC3_SD_CONFIG_SDHC_ExtGateClk3  0x1F0
-
-/* Memory access enable (set to 1 to access SD Controller) */
-#define SD_CONFIG_COMMAND_MAE                (1<<1)
-
-#define SD_CONFIG_CLK_ENABLE_ALL             0x1f
-
-#define SD_CONFIG_POWER1_PC_33V              0x0200    /* Set for 3.3 volts */
-#define SD_CONFIG_POWER1_PC_OFF              0x0000    /* Turn off power */
-
- /* two bits - number of cycles for card detection */
-#define SD_CONFIG_CARDDETECTMODE_CLK           ((x) & 0x3)
-
-
-#define ASIC3_SD_CTRL_Base            0x1000
-
-#define ASIC3_SD_CTRL_Cmd                  0x00
-#define ASIC3_SD_CTRL_Arg0                 0x08
-#define ASIC3_SD_CTRL_Arg1                 0x0C
-#define ASIC3_SD_CTRL_StopInternal         0x10
-#define ASIC3_SD_CTRL_TransferSectorCount  0x14
-#define ASIC3_SD_CTRL_Response0            0x18
-#define ASIC3_SD_CTRL_Response1            0x1C
-#define ASIC3_SD_CTRL_Response2            0x20
-#define ASIC3_SD_CTRL_Response3            0x24
-#define ASIC3_SD_CTRL_Response4            0x28
-#define ASIC3_SD_CTRL_Response5            0x2C
-#define ASIC3_SD_CTRL_Response6            0x30
-#define ASIC3_SD_CTRL_Response7            0x34
-#define ASIC3_SD_CTRL_CardStatus           0x38
-#define ASIC3_SD_CTRL_BufferCtrl           0x3C
-#define ASIC3_SD_CTRL_IntMaskCard          0x40
-#define ASIC3_SD_CTRL_IntMaskBuffer        0x44
-#define ASIC3_SD_CTRL_CardClockCtrl        0x48
-#define ASIC3_SD_CTRL_MemCardXferDataLen   0x4C
-#define ASIC3_SD_CTRL_MemCardOptionSetup   0x50
-#define ASIC3_SD_CTRL_ErrorStatus0         0x58
-#define ASIC3_SD_CTRL_ErrorStatus1         0x5C
-#define ASIC3_SD_CTRL_DataPort             0x60
-#define ASIC3_SD_CTRL_TransactionCtrl      0x68
-#define ASIC3_SD_CTRL_SoftwareReset        0x1C0
-
-#define SD_CTRL_SOFTWARE_RESET_CLEAR            (1<<0)
-
-#define SD_CTRL_TRANSACTIONCONTROL_SET          (1<<8)
-
-#define SD_CTRL_CARDCLOCKCONTROL_FOR_SD_CARD    (1<<15)
-#define SD_CTRL_CARDCLOCKCONTROL_ENABLE_CLOCK   (1<<8)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_512    (1<<7)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_256    (1<<6)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_128    (1<<5)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_64     (1<<4)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_32     (1<<3)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_16     (1<<2)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_8      (1<<1)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_4      (1<<0)
-#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_2      (0<<0)
-
-#define MEM_CARD_OPTION_REQUIRED                   0x000e
-#define MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(x)   (((x) & 0x0f) << 4)
-#define MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT      (1<<14)
-#define MEM_CARD_OPTION_DATA_XFR_WIDTH_1           (1<<15)
-#define MEM_CARD_OPTION_DATA_XFR_WIDTH_4           0
-
-#define SD_CTRL_COMMAND_INDEX(x)                   ((x) & 0x3f)
-#define SD_CTRL_COMMAND_TYPE_CMD                   (0 << 6)
-#define SD_CTRL_COMMAND_TYPE_ACMD                  (1 << 6)
-#define SD_CTRL_COMMAND_TYPE_AUTHENTICATION        (2 << 6)
-#define SD_CTRL_COMMAND_RESPONSE_TYPE_NORMAL       (0 << 8)
-#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1       (4 << 8)
-#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1B      (5 << 8)
-#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R2       (6 << 8)
-#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R3       (7 << 8)
-#define SD_CTRL_COMMAND_DATA_PRESENT               (1 << 11)
-#define SD_CTRL_COMMAND_TRANSFER_READ              (1 << 12)
-#define SD_CTRL_COMMAND_TRANSFER_WRITE             (0 << 12)
-#define SD_CTRL_COMMAND_MULTI_BLOCK                (1 << 13)
-#define SD_CTRL_COMMAND_SECURITY_CMD               (1 << 14)
-
-#define SD_CTRL_STOP_INTERNAL_ISSSUE_CMD12         (1 << 0)
-#define SD_CTRL_STOP_INTERNAL_AUTO_ISSUE_CMD12     (1 << 8)
-
-#define SD_CTRL_CARDSTATUS_RESPONSE_END            (1 << 0)
-#define SD_CTRL_CARDSTATUS_RW_END                  (1 << 2)
-#define SD_CTRL_CARDSTATUS_CARD_REMOVED_0          (1 << 3)
-#define SD_CTRL_CARDSTATUS_CARD_INSERTED_0         (1 << 4)
-#define SD_CTRL_CARDSTATUS_SIGNAL_STATE_PRESENT_0  (1 << 5)
-#define SD_CTRL_CARDSTATUS_WRITE_PROTECT           (1 << 7)
-#define SD_CTRL_CARDSTATUS_CARD_REMOVED_3          (1 << 8)
-#define SD_CTRL_CARDSTATUS_CARD_INSERTED_3         (1 << 9)
-#define SD_CTRL_CARDSTATUS_SIGNAL_STATE_PRESENT_3  (1 << 10)
-
-#define SD_CTRL_BUFFERSTATUS_CMD_INDEX_ERROR       (1 << 0)
-#define SD_CTRL_BUFFERSTATUS_CRC_ERROR             (1 << 1)
-#define SD_CTRL_BUFFERSTATUS_STOP_BIT_END_ERROR    (1 << 2)
-#define SD_CTRL_BUFFERSTATUS_DATA_TIMEOUT          (1 << 3)
-#define SD_CTRL_BUFFERSTATUS_BUFFER_OVERFLOW       (1 << 4)
-#define SD_CTRL_BUFFERSTATUS_BUFFER_UNDERFLOW      (1 << 5)
-#define SD_CTRL_BUFFERSTATUS_CMD_TIMEOUT           (1 << 6)
-#define SD_CTRL_BUFFERSTATUS_UNK7                  (1 << 7)
-#define SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE    (1 << 8)
-#define SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE   (1 << 9)
-#define SD_CTRL_BUFFERSTATUS_ILLEGAL_FUNCTION      (1 << 13)
-#define SD_CTRL_BUFFERSTATUS_CMD_BUSY              (1 << 14)
-#define SD_CTRL_BUFFERSTATUS_ILLEGAL_ACCESS        (1 << 15)
-
-#define SD_CTRL_INTMASKCARD_RESPONSE_END           (1 << 0)
-#define SD_CTRL_INTMASKCARD_RW_END                 (1 << 2)
-#define SD_CTRL_INTMASKCARD_CARD_REMOVED_0         (1 << 3)
-#define SD_CTRL_INTMASKCARD_CARD_INSERTED_0        (1 << 4)
-#define SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_0 (1 << 5)
-#define SD_CTRL_INTMASKCARD_UNK6                   (1 << 6)
-#define SD_CTRL_INTMASKCARD_WRITE_PROTECT          (1 << 7)
-#define SD_CTRL_INTMASKCARD_CARD_REMOVED_3         (1 << 8)
-#define SD_CTRL_INTMASKCARD_CARD_INSERTED_3        (1 << 9)
-#define SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_3 (1 << 10)
-
-#define SD_CTRL_INTMASKBUFFER_CMD_INDEX_ERROR      (1 << 0)
-#define SD_CTRL_INTMASKBUFFER_CRC_ERROR            (1 << 1)
-#define SD_CTRL_INTMASKBUFFER_STOP_BIT_END_ERROR   (1 << 2)
-#define SD_CTRL_INTMASKBUFFER_DATA_TIMEOUT         (1 << 3)
-#define SD_CTRL_INTMASKBUFFER_BUFFER_OVERFLOW      (1 << 4)
-#define SD_CTRL_INTMASKBUFFER_BUFFER_UNDERFLOW     (1 << 5)
-#define SD_CTRL_INTMASKBUFFER_CMD_TIMEOUT          (1 << 6)
-#define SD_CTRL_INTMASKBUFFER_UNK7                 (1 << 7)
-#define SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE   (1 << 8)
-#define SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE  (1 << 9)
-#define SD_CTRL_INTMASKBUFFER_ILLEGAL_FUNCTION     (1 << 13)
-#define SD_CTRL_INTMASKBUFFER_CMD_BUSY             (1 << 14)
-#define SD_CTRL_INTMASKBUFFER_ILLEGAL_ACCESS       (1 << 15)
-
-#define SD_CTRL_DETAIL0_RESPONSE_CMD_ERROR                   (1 << 0)
-#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_RESPONSE_NON_CMD12 (1 << 2)
-#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_RESPONSE_CMD12     (1 << 3)
-#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_READ_DATA          (1 << 4)
-#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_WRITE_CRC_STATUS   (1 << 5)
-#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_RESPONSE_NON_CMD12     (1 << 8)
-#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_RESPONSE_CMD12         (1 << 9)
-#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_READ_DATA              (1 << 10)
-#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_WRITE_CMD              (1 << 11)
-
-#define SD_CTRL_DETAIL1_NO_CMD_RESPONSE                      (1 << 0)
-#define SD_CTRL_DETAIL1_TIMEOUT_READ_DATA                    (1 << 4)
-#define SD_CTRL_DETAIL1_TIMEOUT_CRS_STATUS                   (1 << 5)
-#define SD_CTRL_DETAIL1_TIMEOUT_CRC_BUSY                     (1 << 6)
-
-#define ASIC3_SDIO_CTRL_Base          0x1200
-
-#define ASIC3_SDIO_CTRL_Cmd                  0x00
-#define ASIC3_SDIO_CTRL_CardPortSel          0x04
-#define ASIC3_SDIO_CTRL_Arg0                 0x08
-#define ASIC3_SDIO_CTRL_Arg1                 0x0C
-#define ASIC3_SDIO_CTRL_TransferBlockCount   0x14
-#define ASIC3_SDIO_CTRL_Response0            0x18
-#define ASIC3_SDIO_CTRL_Response1            0x1C
-#define ASIC3_SDIO_CTRL_Response2            0x20
-#define ASIC3_SDIO_CTRL_Response3            0x24
-#define ASIC3_SDIO_CTRL_Response4            0x28
-#define ASIC3_SDIO_CTRL_Response5            0x2C
-#define ASIC3_SDIO_CTRL_Response6            0x30
-#define ASIC3_SDIO_CTRL_Response7            0x34
-#define ASIC3_SDIO_CTRL_CardStatus           0x38
-#define ASIC3_SDIO_CTRL_BufferCtrl           0x3C
-#define ASIC3_SDIO_CTRL_IntMaskCard          0x40
-#define ASIC3_SDIO_CTRL_IntMaskBuffer        0x44
-#define ASIC3_SDIO_CTRL_CardXferDataLen      0x4C
-#define ASIC3_SDIO_CTRL_CardOptionSetup      0x50
-#define ASIC3_SDIO_CTRL_ErrorStatus0         0x54
-#define ASIC3_SDIO_CTRL_ErrorStatus1         0x58
-#define ASIC3_SDIO_CTRL_DataPort             0x60
-#define ASIC3_SDIO_CTRL_TransactionCtrl      0x68
-#define ASIC3_SDIO_CTRL_CardIntCtrl          0x6C
-#define ASIC3_SDIO_CTRL_ClocknWaitCtrl       0x70
-#define ASIC3_SDIO_CTRL_HostInformation      0x74
-#define ASIC3_SDIO_CTRL_ErrorCtrl            0x78
-#define ASIC3_SDIO_CTRL_LEDCtrl              0x7C
-#define ASIC3_SDIO_CTRL_SoftwareReset        0x1C0
+#define ASIC3_SD_CONFIG_BASE	0x0400 /* Assumes 32 bit addressing */
+#define ASIC3_SD_CTRL_BASE	0x1000
+#define ASIC3_SDIO_CTRL_BASE	0x1200
 
 #define ASIC3_MAP_SIZE_32BIT	0x2000
 #define ASIC3_MAP_SIZE_16BIT	0x1000
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/7] MFD: ASIC3: enable DS1WM cell.
  2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
                   ` (4 preceding siblings ...)
  2009-06-05 16:31 ` [PATCH 5/7] MFD: ASIC3: remove SD/SDIO controller register definitions Philipp Zabel
@ 2009-06-05 16:31 ` Philipp Zabel
  2009-06-12 22:40   ` pHilipp Zabel
  2009-06-05 16:31 ` [PATCH 7/7] MFD: ASIC3: enable SD/SDIO cell Philipp Zabel
  6 siblings, 1 reply; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

This enables the ASIC3's DS1WM MFD cell, supported by the ds1wm driver.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 drivers/mfd/Kconfig |    1 +
 drivers/mfd/asic3.c |  100 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ee3927a..9e6d5ee 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -30,6 +30,7 @@ config MFD_SM501_GPIO
 config MFD_ASIC3
 	bool "Support for Compaq ASIC3"
 	depends on GENERIC_HARDIRQS && GPIOLIB && ARM
+	select MFD_CORE
 	 ---help---
 	  This driver supports the ASIC3 multifunction chip found on many
 	  PDAs (mainly iPAQ and HTC based ones)
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index d5dd0df..3fadd02 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
@@ -24,6 +25,8 @@
 #include <linux/platform_device.h>
 
 #include <linux/mfd/asic3.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
 
 enum {
 	ASIC3_CLOCK_SPI,
@@ -616,6 +619,99 @@ static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
+/* MFD cells (SPI, PWM, LED, DS1WM, MMC) */
+static struct ds1wm_driver_data ds1wm_pdata = {
+	.active_high = 1,
+};
+
+static struct resource ds1wm_resources[] = {
+	{
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = ASIC3_IRQ_OWM,
+		.start = ASIC3_IRQ_OWM,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	},
+};
+
+static int ds1wm_enable(struct platform_device *pdev)
+{
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	/* Turn on external clocks and the OWM clock */
+	asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]);
+	asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
+	asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_OWM]);
+	msleep(1);
+
+	/* Reset and enable DS1WM */
+	asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET),
+			   ASIC3_EXTCF_OWM_RESET, 1);
+	msleep(1);
+	asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET),
+			   ASIC3_EXTCF_OWM_RESET, 0);
+	msleep(1);
+	asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
+			   ASIC3_EXTCF_OWM_EN, 1);
+	msleep(1);
+
+	return 0;
+}
+
+static int ds1wm_disable(struct platform_device *pdev)
+{
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
+			   ASIC3_EXTCF_OWM_EN, 0);
+
+	asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_OWM]);
+	asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX0]);
+	asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
+
+	return 0;
+}
+
+static struct mfd_cell asic3_cell_ds1wm = {
+	.name          = "ds1wm",
+	.enable        = ds1wm_enable,
+	.disable       = ds1wm_disable,
+	.driver_data   = &ds1wm_pdata,
+	.num_resources = ARRAY_SIZE(ds1wm_resources),
+	.resources     = ds1wm_resources,
+};
+
+static int __init asic3_mfd_probe(struct platform_device *pdev,
+				  struct resource *mem)
+{
+	struct asic3 *asic = platform_get_drvdata(pdev);
+	int ret;
+
+	/* DS1WM */
+	asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
+			   ASIC3_EXTCF_OWM_SMB, 0);
+
+	ds1wm_resources[0].start = ASIC3_OWM_BASE >> asic->bus_shift;
+	ds1wm_resources[0].end = ds1wm_resources[0].start
+	                         + (5 << (2 - asic->bus_shift)) - 1;
+
+	asic3_cell_ds1wm.platform_data = &asic3_cell_ds1wm;
+	asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm);
+
+	ret = mfd_add_devices(&pdev->dev, pdev->id,
+			&asic3_cell_ds1wm, 1, mem, asic->irq_base);
+
+	return ret;
+}
+
+static void asic3_mfd_remove(struct platform_device *pdev)
+{
+	struct asic3 *asic = platform_get_drvdata(pdev);
+
+	mfd_remove_devices(&pdev->dev);
+}
+
 /* Core */
 static int __init asic3_probe(struct platform_device *pdev)
 {
@@ -683,6 +779,8 @@ static int __init asic3_probe(struct platform_device *pdev)
 	 */
 	memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init));
 
+	asic3_mfd_probe(pdev, mem);
+
 	dev_info(asic->dev, "ASIC3 Core driver\n");
 
 	return 0;
@@ -704,6 +802,8 @@ static int asic3_remove(struct platform_device *pdev)
 	int ret;
 	struct asic3 *asic = platform_get_drvdata(pdev);
 
+	asic3_mfd_remove(pdev);
+
 	ret = asic3_gpio_remove(pdev);
 	if (ret < 0)
 		return ret;
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/7] MFD: ASIC3: enable SD/SDIO cell
  2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
                   ` (5 preceding siblings ...)
  2009-06-05 16:31 ` [PATCH 6/7] MFD: ASIC3: enable DS1WM cell Philipp Zabel
@ 2009-06-05 16:31 ` Philipp Zabel
  6 siblings, 0 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-05 16:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

This enables the ASIC3's SD/SDIO MFD cell, supported by the tmio_mmc driver.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 drivers/mfd/asic3.c |  116 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 113 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 3fadd02..895d365 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -27,6 +27,7 @@
 #include <linux/mfd/asic3.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/ds1wm.h>
+#include <linux/mfd/tmio.h>
 
 enum {
 	ASIC3_CLOCK_SPI,
@@ -682,11 +683,106 @@ static struct mfd_cell asic3_cell_ds1wm = {
 	.resources     = ds1wm_resources,
 };
 
+static struct tmio_mmc_data asic3_mmc_data = {
+	.hclk = 24576000,
+};
+
+static struct resource asic3_mmc_resources[] = {
+	{
+		.start = ASIC3_SD_CTRL_BASE,
+		.end   = ASIC3_SD_CTRL_BASE + 0x3ff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = ASIC3_SD_CONFIG_BASE,
+		.end   = ASIC3_SD_CONFIG_BASE + 0x1ff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0,
+		.end   = 0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static int asic3_mmc_enable(struct platform_device *pdev)
+{
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	/* Not sure if it must be done bit by bit, but leaving as-is */
+	asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF),
+			   ASIC3_SDHWCTRL_LEVCD, 1);
+	asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF),
+			   ASIC3_SDHWCTRL_LEVWP, 1);
+	asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF),
+			   ASIC3_SDHWCTRL_SUSPEND, 0);
+	asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF),
+			   ASIC3_SDHWCTRL_PCLR, 0);
+
+	asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]);
+	/* CLK32 used for card detection and for interruption detection
+	 * when HCLK is stopped.
+	 */
+	asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
+	msleep(1);
+
+	/* HCLK 24.576 MHz, BCLK 12.288 MHz: */
+	asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL),
+		CLOCK_SEL_CX | CLOCK_SEL_SD_HCLK_SEL);
+
+	asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]);
+	asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]);
+	msleep(1);
+
+	asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
+			   ASIC3_EXTCF_SD_MEM_ENABLE, 1);
+
+	/* Enable SD card slot 3.3V power supply */
+	asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF),
+			   ASIC3_SDHWCTRL_SDPWR, 1);
+
+	return 0;
+}
+
+static int asic3_mmc_disable(struct platform_device *pdev)
+{
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	/* Put in suspend mode */
+	asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF),
+			   ASIC3_SDHWCTRL_SUSPEND, 1);
+
+	/* Disable clocks */
+	asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]);
+	asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]);
+	asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX0]);
+	asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
+	return 0;
+}
+
+static struct mfd_cell asic3_cell_mmc = {
+	.name = "tmio-mmc",
+	.enable = asic3_mmc_enable,
+	.disable = asic3_mmc_disable,
+	.driver_data = &asic3_mmc_data,
+	.num_resources = ARRAY_SIZE(asic3_mmc_resources),
+	.resources = asic3_mmc_resources,
+};
+
 static int __init asic3_mfd_probe(struct platform_device *pdev,
 				  struct resource *mem)
 {
 	struct asic3 *asic = platform_get_drvdata(pdev);
-	int ret;
+	struct resource *mem_sdio;
+	int irq, ret;
+
+	mem_sdio = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!mem_sdio)
+		dev_dbg(asic->dev, "no SDIO MEM resource\n");
+
+	irq = platform_get_irq(pdev, 1);
+	if (irq < 0)
+		dev_dbg(asic->dev, "no SDIO IRQ resource\n");
 
 	/* DS1WM */
 	asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
@@ -699,16 +795,30 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
 	asic3_cell_ds1wm.platform_data = &asic3_cell_ds1wm;
 	asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm);
 
+	/* MMC */
+	asic3_mmc_resources[0].start >>= (2 - asic->bus_shift);
+	asic3_mmc_resources[0].end   >>= (2 - asic->bus_shift);
+	asic3_mmc_resources[1].start >>= (2 - asic->bus_shift);
+	asic3_mmc_resources[1].end   >>= (2 - asic->bus_shift);
+
+	asic3_cell_mmc.platform_data = &asic3_cell_mmc;
+	asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc);
+
 	ret = mfd_add_devices(&pdev->dev, pdev->id,
 			&asic3_cell_ds1wm, 1, mem, asic->irq_base);
+	if (ret < 0)
+		goto out;
 
+	if (mem_sdio && (irq >= 0))
+		ret = mfd_add_devices(&pdev->dev, pdev->id,
+			&asic3_cell_mmc, 1, mem_sdio, irq);
+
+ out:
 	return ret;
 }
 
 static void asic3_mfd_remove(struct platform_device *pdev)
 {
-	struct asic3 *asic = platform_get_drvdata(pdev);
-
 	mfd_remove_devices(&pdev->dev);
 }
 
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 6/7] MFD: ASIC3: enable DS1WM cell.
  2009-06-05 16:31 ` [PATCH 6/7] MFD: ASIC3: enable DS1WM cell Philipp Zabel
@ 2009-06-12 22:40   ` pHilipp Zabel
  0 siblings, 0 replies; 10+ messages in thread
From: pHilipp Zabel @ 2009-06-12 22:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

On Fri, Jun 5, 2009 at 6:31 PM, Philipp Zabel<philipp.zabel@gmail.com> wrote:
> This enables the ASIC3's DS1WM MFD cell, supported by the ds1wm driver.
>
> Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
> ---
>  drivers/mfd/Kconfig |    1 +
>  drivers/mfd/asic3.c |  100 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 101 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index ee3927a..9e6d5ee 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -30,6 +30,7 @@ config MFD_SM501_GPIO
>  config MFD_ASIC3
>        bool "Support for Compaq ASIC3"
>        depends on GENERIC_HARDIRQS && GPIOLIB && ARM
> +       select MFD_CORE
>         ---help---
>          This driver supports the ASIC3 multifunction chip found on many
>          PDAs (mainly iPAQ and HTC based ones)
> diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
> index d5dd0df..3fadd02 100644
> --- a/drivers/mfd/asic3.c
> +++ b/drivers/mfd/asic3.c
> @@ -17,6 +17,7 @@
>  */
>
>  #include <linux/kernel.h>
> +#include <linux/delay.h>
>  #include <linux/irq.h>
>  #include <linux/gpio.h>
>  #include <linux/io.h>
> @@ -24,6 +25,8 @@
>  #include <linux/platform_device.h>
>
>  #include <linux/mfd/asic3.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/ds1wm.h>
>
>  enum {
>        ASIC3_CLOCK_SPI,
> @@ -616,6 +619,99 @@ static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
>        spin_unlock_irqrestore(&asic->lock, flags);
>  }
>
> +/* MFD cells (SPI, PWM, LED, DS1WM, MMC) */
> +static struct ds1wm_driver_data ds1wm_pdata = {
> +       .active_high = 1,
> +};
> +
> +static struct resource ds1wm_resources[] = {
> +       {
> +               .flags = IORESOURCE_MEM,
> +       },
> +       {
> +               .start = ASIC3_IRQ_OWM,
> +               .start = ASIC3_IRQ_OWM,
> +               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
> +       },
> +};
> +
> +static int ds1wm_enable(struct platform_device *pdev)
> +{
> +       struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
> +
> +       /* Turn on external clocks and the OWM clock */
> +       asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]);
> +       asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
> +       asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_OWM]);
> +       msleep(1);
> +
> +       /* Reset and enable DS1WM */
> +       asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET),
> +                          ASIC3_EXTCF_OWM_RESET, 1);
> +       msleep(1);
> +       asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET),
> +                          ASIC3_EXTCF_OWM_RESET, 0);
> +       msleep(1);
> +       asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
> +                          ASIC3_EXTCF_OWM_EN, 1);
> +       msleep(1);
> +
> +       return 0;
> +}
> +
> +static int ds1wm_disable(struct platform_device *pdev)
> +{
> +       struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
> +
> +       asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
> +                          ASIC3_EXTCF_OWM_EN, 0);
> +
> +       asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_OWM]);
> +       asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX0]);
> +       asic3_clk_disable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
> +
> +       return 0;
> +}
> +
> +static struct mfd_cell asic3_cell_ds1wm = {
> +       .name          = "ds1wm",
> +       .enable        = ds1wm_enable,
> +       .disable       = ds1wm_disable,
> +       .driver_data   = &ds1wm_pdata,
> +       .num_resources = ARRAY_SIZE(ds1wm_resources),
> +       .resources     = ds1wm_resources,
> +};
> +
> +static int __init asic3_mfd_probe(struct platform_device *pdev,
> +                                 struct resource *mem)
> +{
> +       struct asic3 *asic = platform_get_drvdata(pdev);
> +       int ret;
> +
> +       /* DS1WM */
> +       asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
> +                          ASIC3_EXTCF_OWM_SMB, 0);
> +
> +       ds1wm_resources[0].start = ASIC3_OWM_BASE >> asic->bus_shift;
> +       ds1wm_resources[0].end = ds1wm_resources[0].start
> +                                + (5 << (2 - asic->bus_shift)) - 1;
> +
> +       asic3_cell_ds1wm.platform_data = &asic3_cell_ds1wm;
> +       asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm);
> +
> +       ret = mfd_add_devices(&pdev->dev, pdev->id,
> +                       &asic3_cell_ds1wm, 1, mem, asic->irq_base);
> +
> +       return ret;
> +}
> +
> +static void asic3_mfd_remove(struct platform_device *pdev)
> +{
> +       struct asic3 *asic = platform_get_drvdata(pdev);
> +
> +       mfd_remove_devices(&pdev->dev);
> +}

I've just noticed that the following hunk got squashed into 7/7 instead of 6/7:

--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -737,8 +737,6 @@ static int __init asic3_mfd_probe(struct platform_device *pd

 static void asic3_mfd_remove(struct platform_device *pdev)
 {
-       struct asic3 *asic = platform_get_drvdata(pdev);
-
        mfd_remove_devices(&pdev->dev);
 }

Please consider replacing those two with the fixed versions I'll send.

> +
>  /* Core */
>  static int __init asic3_probe(struct platform_device *pdev)
>  {
> @@ -683,6 +779,8 @@ static int __init asic3_probe(struct platform_device *pdev)
>         */
>        memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init));
>
> +       asic3_mfd_probe(pdev, mem);
> +
>        dev_info(asic->dev, "ASIC3 Core driver\n");
>
>        return 0;
> @@ -704,6 +802,8 @@ static int asic3_remove(struct platform_device *pdev)
>        int ret;
>        struct asic3 *asic = platform_get_drvdata(pdev);
>
> +       asic3_mfd_remove(pdev);
> +
>        ret = asic3_gpio_remove(pdev);
>        if (ret < 0)
>                return ret;
> --
> 1.6.3.1
>
>

regards
Philipp

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/7] MFD: ASIC3: add ASIC3 IRQ numbers
  2009-06-04 18:36 [PATCH 0/7] ASIC3 updates Philipp Zabel
@ 2009-06-04 18:36 ` Philipp Zabel
  0 siblings, 0 replies; 10+ messages in thread
From: Philipp Zabel @ 2009-06-04 18:36 UTC (permalink / raw)
  To: linux-kernel; +Cc: Samuel Ortiz, Philipp Zabel

IRQ number definitions for PWM, LED, SPI and OWM (ds1wm).

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
---
 include/linux/mfd/asic3.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h
index cd02d20..5fc3aa4 100644
--- a/include/linux/mfd/asic3.h
+++ b/include/linux/mfd/asic3.h
@@ -33,6 +33,13 @@ struct asic3_platform_data {
 #define ASIC3_NUM_GPIOS		64
 #define ASIC3_NR_IRQS		ASIC3_NUM_GPIOS + 6
 
+#define ASIC3_IRQ_LED0		64
+#define ASIC3_IRQ_LED1		65
+#define ASIC3_IRQ_LED2		66
+#define ASIC3_IRQ_SPI		67
+#define ASIC3_IRQ_SMBUS		68
+#define ASIC3_IRQ_OWM		69
+
 #define ASIC3_TO_GPIO(gpio) (NR_BUILTIN_GPIO + (gpio))
 
 #define ASIC3_GPIO_BANK_A	0
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-06-12 22:40 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-05 16:31 [PATCH 0/7] ASIC3 updates (v2) Philipp Zabel
2009-06-05 16:31 ` [PATCH 1/7] MFD: ASIC3: add asic3_set_register common operation Philipp Zabel
2009-06-05 16:31 ` [PATCH 2/7] MFD: ASIC3: add clock handling for MFD cells Philipp Zabel
2009-06-05 16:31 ` [PATCH 3/7] MFD: ASIC3: add ASIC3 IRQ numbers Philipp Zabel
2009-06-05 16:31 ` [PATCH 4/7] MFD: ASIC3: use resource_size macro instead of local variable Philipp Zabel
2009-06-05 16:31 ` [PATCH 5/7] MFD: ASIC3: remove SD/SDIO controller register definitions Philipp Zabel
2009-06-05 16:31 ` [PATCH 6/7] MFD: ASIC3: enable DS1WM cell Philipp Zabel
2009-06-12 22:40   ` pHilipp Zabel
2009-06-05 16:31 ` [PATCH 7/7] MFD: ASIC3: enable SD/SDIO cell Philipp Zabel
  -- strict thread matches above, loose matches on Subject: below --
2009-06-04 18:36 [PATCH 0/7] ASIC3 updates Philipp Zabel
2009-06-04 18:36 ` [PATCH 3/7] MFD: ASIC3: add ASIC3 IRQ numbers Philipp Zabel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.