diff options
Diffstat (limited to 'arch/arm/mach-u300')
-rw-r--r-- | arch/arm/mach-u300/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-u300/core.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/gpio.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-u300/i2c.c | 249 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/coh901318.h | 281 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/gpio.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/u300-regs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/mmc.c | 64 | ||||
-rw-r--r-- | arch/arm/mach-u300/regulator.c | 88 |
9 files changed, 636 insertions, 62 deletions
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index 885b5c027c1..fab46fe9a71 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_MMC) += mmc.o obj-$(CONFIG_SPI_PL022) += spi.o obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.o obj-$(CONFIG_I2C_STU300) += i2c.o +obj-$(CONFIG_REGULATOR_AB3100) += regulator.o diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index be60d6deee8..653e25be3dd 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -408,7 +408,7 @@ static struct platform_device keypad_device = { }; static struct platform_device rtc_device = { - .name = "rtc0", + .name = "rtc-coh901331", .id = -1, .num_resources = ARRAY_SIZE(rtc_resources), .resource = rtc_resources, diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c index 63c8f27fb15..0b35826b7d1 100644 --- a/arch/arm/mach-u300/gpio.c +++ b/arch/arm/mach-u300/gpio.c @@ -281,6 +281,16 @@ int gpio_unregister_callback(unsigned gpio) } EXPORT_SYMBOL(gpio_unregister_callback); +/* Non-zero means valid */ +int gpio_is_valid(int number) +{ + if (number >= 0 && + number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT)) + return 1; + return 0; +} +EXPORT_SYMBOL(gpio_is_valid); + int gpio_request(unsigned gpio, const char *label) { if (gpio_pin[gpio].users) diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c index 10be1f888b2..c73ed06b606 100644 --- a/arch/arm/mach-u300/i2c.c +++ b/arch/arm/mach-u300/i2c.c @@ -9,13 +9,257 @@ */ #include <linux/kernel.h> #include <linux/i2c.h> +#include <linux/mfd/ab3100.h> +#include <linux/regulator/machine.h> +#include <linux/amba/bus.h> #include <mach/irqs.h> +/* + * Initial settings of ab3100 registers. + * Common for below LDO regulator settings are that + * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0). + * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode. + */ + +/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */ +#define LDO_A_SETTING 0x16 +/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */ +#define LDO_C_SETTING 0x10 +/* LDO_D 0x10: 2.65V, ON, sleep mode not used */ +#define LDO_D_SETTING 0x10 +/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */ +#define LDO_E_SETTING 0x10 +/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */ +#define LDO_E_SLEEP_SETTING 0x00 +/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */ +#define LDO_F_SETTING 0xD0 +/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */ +#define LDO_G_SETTING 0x00 +/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */ +#define LDO_H_SETTING 0x18 +/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */ +#define LDO_K_SETTING 0x00 +/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */ +#define LDO_EXT_SETTING 0x00 +/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */ +#define BUCK_SETTING 0x7D +/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */ +#define BUCK_SLEEP_SETTING 0xAC + +static struct regulator_consumer_supply supply_ldo_c[] = { + { + .dev_name = "ab3100-codec", + .supply = "vaudio", /* Powers the codec */ + }, +}; + +/* + * This one needs to be a supply so we can turn it off + * in order to shut down the system. + */ +static struct regulator_consumer_supply supply_ldo_d[] = { + { + .dev = NULL, + .supply = "vana15", /* Powers the SoC (CPU etc) */ + }, +}; + +static struct regulator_consumer_supply supply_ldo_g[] = { + { + .dev_name = "mmci", + .supply = "vmmc", /* Powers MMC/SD card */ + }, +}; + +static struct regulator_consumer_supply supply_ldo_h[] = { + { + .dev_name = "xgam_pdi", + .supply = "vdisp", /* Powers camera, display etc */ + }, +}; + +static struct regulator_consumer_supply supply_ldo_k[] = { + { + .dev_name = "irda", + .supply = "vir", /* Power IrDA */ + }, +}; + +/* + * This is a placeholder for whoever wish to use the + * external power. + */ +static struct regulator_consumer_supply supply_ldo_ext[] = { + { + .dev = NULL, + .supply = "vext", /* External power */ + }, +}; + +/* Preset (hardware defined) voltages for these regulators */ +#define LDO_A_VOLTAGE 2750000 +#define LDO_C_VOLTAGE 2650000 +#define LDO_D_VOLTAGE 2650000 + +static struct ab3100_platform_data ab3100_plf_data = { + .reg_constraints = { + /* LDO A routing and constraints */ + { + .constraints = { + .name = "vrad", + .min_uV = LDO_A_VOLTAGE, + .max_uV = LDO_A_VOLTAGE, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .always_on = 1, + .boot_on = 1, + }, + }, + /* LDO C routing and constraints */ + { + .constraints = { + .min_uV = LDO_C_VOLTAGE, + .max_uV = LDO_C_VOLTAGE, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + }, + .num_consumer_supplies = ARRAY_SIZE(supply_ldo_c), + .consumer_supplies = supply_ldo_c, + }, + /* LDO D routing and constraints */ + { + .constraints = { + .min_uV = LDO_D_VOLTAGE, + .max_uV = LDO_D_VOLTAGE, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + /* + * Actually this is boot_on but we need + * to reference count it externally to + * be able to shut down the system. + */ + }, + .num_consumer_supplies = ARRAY_SIZE(supply_ldo_d), + .consumer_supplies = supply_ldo_d, + }, + /* LDO E routing and constraints */ + { + .constraints = { + .name = "vio", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .always_on = 1, + .boot_on = 1, + }, + }, + /* LDO F routing and constraints */ + { + .constraints = { + .name = "vana25", + .min_uV = 2500000, + .max_uV = 2500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .always_on = 1, + .boot_on = 1, + }, + }, + /* LDO G routing and constraints */ + { + .constraints = { + .min_uV = 1500000, + .max_uV = 2850000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(supply_ldo_g), + .consumer_supplies = supply_ldo_g, + }, + /* LDO H routing and constraints */ + { + .constraints = { + .min_uV = 1200000, + .max_uV = 2750000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(supply_ldo_h), + .consumer_supplies = supply_ldo_h, + }, + /* LDO K routing and constraints */ + { + .constraints = { + .min_uV = 1800000, + .max_uV = 2750000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(supply_ldo_k), + .consumer_supplies = supply_ldo_k, + }, + /* External regulator interface. No fixed voltage specified. + * If we knew the voltage of the external regulator and it + * was connected on the board, we could add the (fixed) + * voltage for it here. + */ + { + .constraints = { + .min_uV = 0, + .max_uV = 0, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(supply_ldo_ext), + .consumer_supplies = supply_ldo_ext, + }, + /* Buck converter routing and constraints */ + { + .constraints = { + .name = "vcore", + .min_uV = 1200000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .always_on = 1, + .boot_on = 1, + }, + }, + }, + .reg_initvals = { + LDO_A_SETTING, + LDO_C_SETTING, + LDO_E_SETTING, + LDO_E_SLEEP_SETTING, + LDO_F_SETTING, + LDO_G_SETTING, + LDO_H_SETTING, + LDO_K_SETTING, + LDO_EXT_SETTING, + BUCK_SETTING, + BUCK_SLEEP_SETTING, + LDO_D_SETTING, + }, +}; + static struct i2c_board_info __initdata bus0_i2c_board_info[] = { { .type = "ab3100", .addr = 0x48, .irq = IRQ_U300_IRQ0_EXT, + .platform_data = &ab3100_plf_data, }, }; @@ -38,6 +282,11 @@ void __init u300_i2c_register_board_devices(void) { i2c_register_board_info(0, bus0_i2c_board_info, ARRAY_SIZE(bus0_i2c_board_info)); + /* + * This makes the core shut down all unused regulators + * after all the initcalls have completed. + */ + regulator_has_full_constraints(); i2c_register_board_info(1, bus1_i2c_board_info, ARRAY_SIZE(bus1_i2c_board_info)); } diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h new file mode 100644 index 00000000000..f4cfee9c7d2 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -0,0 +1,281 @@ +/* + * + * include/linux/coh901318.h + * + * + * Copyright (C) 2007-2009 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * DMA driver for COH 901 318 + * Author: Per Friden <per.friden@stericsson.com> + */ + +#ifndef COH901318_H +#define COH901318_H + +#include <linux/device.h> +#include <linux/dmaengine.h> + +#define MAX_DMA_PACKET_SIZE_SHIFT 11 +#define MAX_DMA_PACKET_SIZE (1 << MAX_DMA_PACKET_SIZE_SHIFT) + +/** + * struct coh901318_lli - linked list item for DMAC + * @control: control settings for DMAC + * @src_addr: transfer source address + * @dst_addr: transfer destination address + * @link_addr: physical address to next lli + * @virt_link_addr: virtual addres of next lli (only used by pool_free) + * @phy_this: physical address of current lli (only used by pool_free) + */ +struct coh901318_lli { + u32 control; + dma_addr_t src_addr; + dma_addr_t dst_addr; + dma_addr_t link_addr; + + void *virt_link_addr; + dma_addr_t phy_this; +}; +/** + * struct coh901318_params - parameters for DMAC configuration + * @config: DMA config register + * @ctrl_lli_last: DMA control register for the last lli in the list + * @ctrl_lli: DMA control register for an lli + * @ctrl_lli_chained: DMA control register for a chained lli + */ +struct coh901318_params { + u32 config; + u32 ctrl_lli_last; + u32 ctrl_lli; + u32 ctrl_lli_chained; +}; +/** + * struct coh_dma_channel - dma channel base + * @name: ascii name of dma channel + * @number: channel id number + * @desc_nbr_max: number of preallocated descriptortors + * @priority_high: prio of channel, 0 low otherwise high. + * @param: configuration parameters + * @dev_addr: physical address of periphal connected to channel + */ +struct coh_dma_channel { + const char name[32]; + const int number; + const int desc_nbr_max; + const int priority_high; + const struct coh901318_params param; + const dma_addr_t dev_addr; +}; + +/** + * dma_access_memory_state_t - register dma for memory access + * + * @dev: The dma device + * @active: 1 means dma intends to access memory + * 0 means dma wont access memory + */ +typedef void (*dma_access_memory_state_t)(struct device *dev, + bool active); + +/** + * struct powersave - DMA power save structure + * @lock: lock protecting data in this struct + * @started_channels: bit mask indicating active dma channels + */ +struct powersave { + spinlock_t lock; + u64 started_channels; +}; +/** + * struct coh901318_platform - platform arch structure + * @chans_slave: specifying dma slave channels + * @chans_memcpy: specifying dma memcpy channels + * @access_memory_state: requesting DMA memeory access (on / off) + * @chan_conf: dma channel configurations + * @max_channels: max number of dma chanenls + */ +struct coh901318_platform { + const int *chans_slave; + const int *chans_memcpy; + const dma_access_memory_state_t access_memory_state; + const struct coh_dma_channel *chan_conf; + const int max_channels; +}; + +/** + * coh901318_get_bytes_left() - Get number of bytes left on a current transfer + * @chan: dma channel handle + * return number of bytes left, or negative on error + */ +u32 coh901318_get_bytes_left(struct dma_chan *chan); + +/** + * coh901318_stop() - Stops dma transfer + * @chan: dma channel handle + * return 0 on success otherwise negative value + */ +void coh901318_stop(struct dma_chan *chan); + +/** + * coh901318_continue() - Resumes a stopped dma transfer + * @chan: dma channel handle + * return 0 on success otherwise negative value + */ +void coh901318_continue(struct dma_chan *chan); + +/** + * coh901318_filter_id() - DMA channel filter function + * @chan: dma channel handle + * @chan_id: id of dma channel to be filter out + * + * In dma_request_channel() it specifies what channel id to be requested + */ +bool coh901318_filter_id(struct dma_chan *chan, void *chan_id); + +/* + * DMA Controller - this access the static mappings of the coh901318 dma. + * + */ + +#define COH901318_MOD32_MASK (0x1F) +#define COH901318_WORD_MASK (0xFFFFFFFF) +/* INT_STATUS - Interrupt Status Registers 32bit (R/-) */ +#define COH901318_INT_STATUS1 (0x0000) +#define COH901318_INT_STATUS2 (0x0004) +/* TC_INT_STATUS - Terminal Count Interrupt Status Registers 32bit (R/-) */ +#define COH901318_TC_INT_STATUS1 (0x0008) +#define COH901318_TC_INT_STATUS2 (0x000C) +/* TC_INT_CLEAR - Terminal Count Interrupt Clear Registers 32bit (-/W) */ +#define COH901318_TC_INT_CLEAR1 (0x0010) +#define COH901318_TC_INT_CLEAR2 (0x0014) +/* RAW_TC_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */ +#define COH901318_RAW_TC_INT_STATUS1 (0x0018) +#define COH901318_RAW_TC_INT_STATUS2 (0x001C) +/* BE_INT_STATUS - Bus Error Interrupt Status Registers 32bit (R/-) */ +#define COH901318_BE_INT_STATUS1 (0x0020) +#define COH901318_BE_INT_STATUS2 (0x0024) +/* BE_INT_CLEAR - Bus Error Interrupt Clear Registers 32bit (-/W) */ +#define COH901318_BE_INT_CLEAR1 (0x0028) +#define COH901318_BE_INT_CLEAR2 (0x002C) +/* RAW_BE_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */ +#define COH901318_RAW_BE_INT_STATUS1 (0x0030) +#define COH901318_RAW_BE_INT_STATUS2 (0x0034) + +/* + * CX_CFG - Channel Configuration Registers 32bit (R/W) + */ +#define COH901318_CX_CFG (0x0100) +#define COH901318_CX_CFG_SPACING (0x04) +/* Channel enable activates tha dma job */ +#define COH901318_CX_CFG_CH_ENABLE (0x00000001) +#define COH901318_CX_CFG_CH_DISABLE (0x00000000) +/* Request Mode */ +#define COH901318_CX_CFG_RM_MASK (0x00000006) +#define COH901318_CX_CFG_RM_MEMORY_TO_MEMORY (0x0 << 1) +#define COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY (0x1 << 1) +#define COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY (0x1 << 1) +#define COH901318_CX_CFG_RM_PRIMARY_TO_SECONDARY (0x3 << 1) +#define COH901318_CX_CFG_RM_SECONDARY_TO_PRIMARY (0x3 << 1) +/* Linked channel request field. RM must == 11 */ +#define COH901318_CX_CFG_LCRF_SHIFT 3 +#define COH901318_CX_CFG_LCRF_MASK (0x000001F8) +#define COH901318_CX_CFG_LCR_DISABLE (0x00000000) +/* Terminal Counter Interrupt Request Mask */ +#define COH901318_CX_CFG_TC_IRQ_ENABLE (0x00000200) +#define COH901318_CX_CFG_TC_IRQ_DISABLE (0x00000000) +/* Bus Error interrupt Mask */ +#define COH901318_CX_CFG_BE_IRQ_ENABLE (0x00000400) +#define COH901318_CX_CFG_BE_IRQ_DISABLE (0x00000000) + +/* + * CX_STAT - Channel Status Registers 32bit (R/-) + */ +#define COH901318_CX_STAT (0x0200) +#define COH901318_CX_STAT_SPACING (0x04) +#define COH901318_CX_STAT_RBE_IRQ_IND (0x00000008) +#define COH901318_CX_STAT_RTC_IRQ_IND (0x00000004) +#define COH901318_CX_STAT_ACTIVE (0x00000002) +#define COH901318_CX_STAT_ENABLED (0x00000001) + +/* + * CX_CTRL - Channel Control Registers 32bit (R/W) + */ +#define COH901318_CX_CTRL (0x0400) +#define COH901318_CX_CTRL_SPACING (0x10) +/* Transfer Count Enable */ +#define COH901318_CX_CTRL_TC_ENABLE (0x00001000) +#define COH901318_CX_CTRL_TC_DISABLE (0x00000000) +/* Transfer Count Value 0 - 4095 */ +#define COH901318_CX_CTRL_TC_VALUE_MASK (0x00000FFF) +/* Burst count */ +#define COH901318_CX_CTRL_BURST_COUNT_MASK (0x0000E000) +#define COH901318_CX_CTRL_BURST_COUNT_64_BYTES (0x7 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_48_BYTES (0x6 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_32_BYTES (0x5 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_16_BYTES (0x4 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_8_BYTES (0x3 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_4_BYTES (0x2 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_2_BYTES (0x1 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_1_BYTE (0x0 << 13) +/* Source bus size */ +#define COH901318_CX_CTRL_SRC_BUS_SIZE_MASK (0x00030000) +#define COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS (0x2 << 16) +#define COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS (0x1 << 16) +#define COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS (0x0 << 16) +/* Source address increment */ +#define COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE (0x00040000) +#define COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE (0x00000000) +/* Destination Bus Size */ +#define COH901318_CX_CTRL_DST_BUS_SIZE_MASK (0x00180000) +#define COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS (0x2 << 19) +#define COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS (0x1 << 19) +#define COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS (0x0 << 19) +/* Destination address increment */ +#define COH901318_CX_CTRL_DST_ADDR_INC_ENABLE (0x00200000) +#define COH901318_CX_CTRL_DST_ADDR_INC_DISABLE (0x00000000) +/* Master Mode (Master2 is only connected to MSL) */ +#define COH901318_CX_CTRL_MASTER_MODE_MASK (0x00C00000) +#define COH901318_CX_CTRL_MASTER_MODE_M2R_M1W (0x3 << 22) +#define COH901318_CX_CTRL_MASTER_MODE_M1R_M2W (0x2 << 22) +#define COH901318_CX_CTRL_MASTER_MODE_M2RW (0x1 << 22) +#define COH901318_CX_CTRL_MASTER_MODE_M1RW (0x0 << 22) +/* Terminal Count flag to PER enable */ +#define COH901318_CX_CTRL_TCP_ENABLE (0x01000000) +#define COH901318_CX_CTRL_TCP_DISABLE (0x00000000) +/* Terminal Count flags to CPU enable */ +#define COH901318_CX_CTRL_TC_IRQ_ENABLE (0x02000000) +#define COH901318_CX_CTRL_TC_IRQ_DISABLE (0x00000000) +/* Hand shake to peripheral */ +#define COH901318_CX_CTRL_HSP_ENABLE (0x04000000) +#define COH901318_CX_CTRL_HSP_DISABLE (0x00000000) +#define COH901318_CX_CTRL_HSS_ENABLE (0x08000000) +#define COH901318_CX_CTRL_HSS_DISABLE (0x00000000) +/* DMA mode */ +#define COH901318_CX_CTRL_DDMA_MASK (0x30000000) +#define COH901318_CX_CTRL_DDMA_LEGACY (0x0 << 28) +#define COH901318_CX_CTRL_DDMA_DEMAND_DMA1 (0x1 << 28) +#define COH901318_CX_CTRL_DDMA_DEMAND_DMA2 (0x2 << 28) +/* Primary Request Data Destination */ +#define COH901318_CX_CTRL_PRDD_MASK (0x40000000) +#define COH901318_CX_CTRL_PRDD_DEST (0x1 << 30) +#define COH901318_CX_CTRL_PRDD_SOURCE (0x0 << 30) + +/* + * CX_SRC_ADDR - Channel Source Address Registers 32bit (R/W) + */ +#define COH901318_CX_SRC_ADDR (0x0404) +#define COH901318_CX_SRC_ADDR_SPACING (0x10) + +/* + * CX_DST_ADDR - Channel Destination Address Registers 32bit R/W + */ +#define COH901318_CX_DST_ADDR (0x0408) +#define COH901318_CX_DST_ADDR_SPACING (0x10) + +/* + * CX_LNK_ADDR - Channel Link Address Registers 32bit (R/W) + */ +#define COH901318_CX_LNK_ADDR (0x040C) +#define COH901318_CX_LNK_ADDR_SPACING (0x10) +#define COH901318_CX_LNK_LINK_IMMEDIATE (0x00000001) +#endif /* COH901318_H */ diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h index c8174128d7e..7b1fc984abb 100644 --- a/arch/arm/mach-u300/include/mach/gpio.h +++ b/arch/arm/mach-u300/include/mach/gpio.h @@ -258,6 +258,7 @@ #define PIN_TO_PORT(val) (val >> 3) /* These can be found in arch/arm/mach-u300/gpio.c */ +extern int gpio_is_valid(int number); extern int gpio_request(unsigned gpio, const char *label); extern void gpio_free(unsigned gpio); extern int gpio_direction_input(unsigned gpio); diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h index 88333dfb19f..56721a0cd2a 100644 --- a/arch/arm/mach-u300/include/mach/u300-regs.h +++ b/arch/arm/mach-u300/include/mach/u300-regs.h @@ -6,7 +6,7 @@ * Copyright (C) 2006-2009 ST-Ericsson AB * License terms: GNU General Public License (GPL) version 2 * Basic register address definitions in physical memory and - * some block defintions for core devices like the timer. + * some block definitions for core devices like the timer. * Author: Linus Walleij <linus.walleij@stericsson.com> */ diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index 7b6b016786b..109f5a6e71c 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c @@ -40,64 +40,6 @@ static unsigned int mmc_status(struct device *dev) return mmci_card->mmc_inserted; } -/* - * Here follows a large chunk of code which will only be enabled if you - * have both the AB3100 chip mounted and the MMC subsystem activated. - */ - -static u32 mmc_translate_vdd(struct device *dev, unsigned int voltage) -{ - int v; - - /* - * MMC Spec: - * bit 7: 1.70 - 1.95V - * bit 8 - 14: 2.0 - 2.6V - * bit 15 - 23: 2.7 - 3.6V - * - * ab3100 voltages: - * 000 - 2.85V - * 001 - 2.75V - * 010 - 1.8V - * 011 - 1.5V - */ - switch (voltage) { - case 8: - v = 3; - break; - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - v = 1; - break; - case 16: - v = 1; - break; - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - v = 0; - break; - default: - v = 0; - break; - } - - /* PL180 voltage register bits */ - return v << 2; -} - - - static int mmci_callback(void *data) { struct mmci_card_event *mmci_card = data; @@ -154,9 +96,11 @@ int __devinit mmc_init(struct amba_device *adev) if (!mmci_card) return -ENOMEM; + /* + * Do not set ocr_mask or voltage translation function, + * we have a regulator we can control instead. + */ /* Nominally 2.85V on our platform */ - mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29; - mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd; mmci_card->mmc0_plat_data.status = mmc_status; mmci_card->mmc0_plat_data.gpio_wp = -1; mmci_card->mmc0_plat_data.gpio_cd = -1; diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c new file mode 100644 index 00000000000..9c53f01c62e --- /dev/null +++ b/arch/arm/mach-u300/regulator.c @@ -0,0 +1,88 @@ +/* + * arch/arm/mach-u300/regulator.c + * + * Copyright (C) 2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Handle board-bound regulators and board power not related + * to any devices. + * Author: Linus Walleij <linus.walleij@stericsson.com> + */ +#include <linux/device.h> +#include <linux/signal.h> +#include <linux/err.h> +#include <linux/regulator/consumer.h> +/* Those are just for writing in syscon */ +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/syscon.h> + +/* + * Regulators that power the board and chip and which are + * not copuled to specific drivers are hogged in these + * instances. + */ +static struct regulator *main_power_15; + +/* + * This function is used from pm.h to shut down the system by + * resetting all regulators in turn and then disable regulator + * LDO D (main power). + */ +void u300_pm_poweroff(void) +{ + sigset_t old, all; + + sigfillset(&all); + if (!sigprocmask(SIG_BLOCK, &all, &old)) { + /* Disable LDO D to shut down the system */ + if (main_power_15) + regulator_disable(main_power_15); + else + pr_err("regulator not available to shut down system\n"); + (void) sigprocmask(SIG_SETMASK, &old, NULL); + } + return; +} + +/* + * Hog the regulators needed to power up the board. + */ +static int __init u300_init_boardpower(void) +{ + int err; + u32 val; + + pr_info("U300: setting up board power\n"); + main_power_15 = regulator_get(NULL, "vana15"); + if (IS_ERR(main_power_15)) { + pr_err("could not get vana15"); + return PTR_ERR(main_power_15); + } + err = regulator_enable(main_power_15); + if (err) { + pr_err("could not enable vana15\n"); + return err; + } + + /* + * On U300 a special system controller register pulls up the DC + * until the vana15 (LDO D) regulator comes up. At this point, all + * regulators are set and we do not need power control via + * DC ON anymore. This function will likely be moved whenever + * the rest of the U300 power management is implemented. + */ + pr_info("U300: disable system controller pull-up\n"); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR); + val &= ~U300_SYSCON_PMCR_DCON_ENABLE; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR); + + /* Register globally exported PM poweroff hook */ + pm_power_off = u300_pm_poweroff; + + return 0; +} + +/* + * So at module init time we hog the regulator! + */ +module_init(u300_init_boardpower); |