From 73de16db43f8dcb833ab032ed274b60b23676680 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 8 Nov 2011 09:44:06 +0530 Subject: mfd: Add support for irq over gpio pin to stmpe On many boards, stmpe is present as an separate device (not as part of SoC). Here gpio lines are mostly used for getting interrupts. This patch adds in support to handle irq over gpio pin. Signed-off-by: Viresh Kumar Acked-by: Linus Walleij Signed-off-by: Samuel Ortiz --- include/linux/mfd/stmpe.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux/mfd') diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index be1af7c42e5..270d6613aad 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -61,6 +61,7 @@ struct stmpe_variant_info; * @variant: the detected STMPE model number * @regs: list of addresses of registers which are at different addresses on * different variants. Indexed by one of STMPE_IDX_*. + * @irq: irq number for stmpe * @irq_base: starting IRQ number for internal IRQs * @num_gpios: number of gpios, differs for variants * @ier: cache of IER registers for bus_lock @@ -76,6 +77,7 @@ struct stmpe { struct stmpe_variant_info *variant; const u8 *regs; + int irq; int irq_base; int num_gpios; u8 ier[2]; @@ -183,6 +185,9 @@ struct stmpe_ts_platform_data { * @autosleep_timeout: inactivity timeout in milliseconds for autosleep * @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or * %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used. + * @irq_over_gpio: true if gpio is used to get irq + * @irq_gpio: gpio number over which irq will be requested (significant only if + * irq_over_gpio is true) * @gpio: GPIO-specific platform data * @keypad: keypad-specific platform data * @ts: touchscreen-specific platform data @@ -194,6 +199,8 @@ struct stmpe_platform_data { unsigned int irq_trigger; bool irq_invert_polarity; bool autosleep; + bool irq_over_gpio; + int irq_gpio; int autosleep_timeout; struct stmpe_gpio_platform_data *gpio; -- cgit v1.2.3-70-g09d2 From 289aabdaf943f3676a16908e2c3cc1a1f9877ccb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 Nov 2011 13:41:14 +0000 Subject: mfd: Disable more pulls on WM8994 Disable more pulls by default on WM8994 for a small current saving. Since some designs do leave SPKMODE floating provide platform data to allow that to be left enabled. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8994-core.c | 11 ++++++++--- include/linux/mfd/wm8994/pdata.h | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'include/linux/mfd') diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index ff373dcda2c..776298b313a 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -374,6 +374,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) struct wm8994_pdata *pdata = wm8994->dev->platform_data; const char *devname; int ret, i; + int pulls = 0; dev_set_drvdata(wm8994->dev, wm8994); @@ -516,12 +517,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) } wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; + + if (pdata->spkmode_pu) + pulls |= WM8994_SPKMODE_PU; } - /* Disable LDO pulldowns while the device is active */ + /* Disable unneeded pulls */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, - WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, - 0); + WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD | + WM8994_SPKMODE_PU | WM8994_CSNADDR_PD, + pulls); /* In some system designs where the regulators are not in use, * we can achieve a small reduction in leakage currents by diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index ea32f306dca..54e2fef587d 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -174,6 +174,12 @@ struct wm8994_pdata { * consumption will rise. */ bool ldo_ena_always_driven; + + /* + * SPKMODE must be pulled internally by the device on this + * system. + */ + bool spkmode_pu; }; #endif -- cgit v1.2.3-70-g09d2 From b46a36c0e0adc92c8be2c8a6fa68d979f6eee124 Mon Sep 17 00:00:00 2001 From: "Jett.Zhou" Date: Fri, 11 Nov 2011 15:38:27 +0800 Subject: mfd: Convert 88pm860x to use regmap api Convert the 88pm860x normal bank register read/write to use the register map API. Signed-off-by: Jett.Zhou Reviewed-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-i2c.c | 105 ++++++++++++++++++------------------------- drivers/mfd/Kconfig | 1 + include/linux/mfd/88pm860x.h | 3 +- 3 files changed, 47 insertions(+), 62 deletions(-) (limited to 'include/linux/mfd') diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index f629d6f4e3e..630f1b545fc 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -12,51 +12,20 @@ #include #include #include +#include +#include #include #include -static inline int pm860x_read_device(struct i2c_client *i2c, - int reg, int bytes, void *dest) -{ - unsigned char data; - int ret; - - data = (unsigned char)reg; - ret = i2c_master_send(i2c, &data, 1); - if (ret < 0) - return ret; - - ret = i2c_master_recv(i2c, dest, bytes); - if (ret < 0) - return ret; - return 0; -} - -static inline int pm860x_write_device(struct i2c_client *i2c, - int reg, int bytes, void *src) -{ - unsigned char buf[bytes + 1]; - int ret; - - buf[0] = (unsigned char)reg; - memcpy(&buf[1], src, bytes); - - ret = i2c_master_send(i2c, buf, bytes + 1); - if (ret < 0) - return ret; - return 0; -} - int pm860x_reg_read(struct i2c_client *i2c, int reg) { struct pm860x_chip *chip = i2c_get_clientdata(i2c); - unsigned char data; + struct regmap *map = (i2c == chip->client) ? chip->regmap + : chip->regmap_companion; + unsigned int data; int ret; - mutex_lock(&chip->io_lock); - ret = pm860x_read_device(i2c, reg, 1, &data); - mutex_unlock(&chip->io_lock); - + ret = regmap_read(map, reg, &data); if (ret < 0) return ret; else @@ -68,12 +37,11 @@ int pm860x_reg_write(struct i2c_client *i2c, int reg, unsigned char data) { struct pm860x_chip *chip = i2c_get_clientdata(i2c); + struct regmap *map = (i2c == chip->client) ? chip->regmap + : chip->regmap_companion; int ret; - mutex_lock(&chip->io_lock); - ret = pm860x_write_device(i2c, reg, 1, &data); - mutex_unlock(&chip->io_lock); - + ret = regmap_write(map, reg, data); return ret; } EXPORT_SYMBOL(pm860x_reg_write); @@ -82,12 +50,11 @@ int pm860x_bulk_read(struct i2c_client *i2c, int reg, int count, unsigned char *buf) { struct pm860x_chip *chip = i2c_get_clientdata(i2c); + struct regmap *map = (i2c == chip->client) ? chip->regmap + : chip->regmap_companion; int ret; - mutex_lock(&chip->io_lock); - ret = pm860x_read_device(i2c, reg, count, buf); - mutex_unlock(&chip->io_lock); - + ret = regmap_raw_read(map, reg, buf, count); return ret; } EXPORT_SYMBOL(pm860x_bulk_read); @@ -96,12 +63,11 @@ int pm860x_bulk_write(struct i2c_client *i2c, int reg, int count, unsigned char *buf) { struct pm860x_chip *chip = i2c_get_clientdata(i2c); + struct regmap *map = (i2c == chip->client) ? chip->regmap + : chip->regmap_companion; int ret; - mutex_lock(&chip->io_lock); - ret = pm860x_write_device(i2c, reg, count, buf); - mutex_unlock(&chip->io_lock); - + ret = regmap_raw_write(map, reg, buf, count); return ret; } EXPORT_SYMBOL(pm860x_bulk_write); @@ -110,18 +76,11 @@ int pm860x_set_bits(struct i2c_client *i2c, int reg, unsigned char mask, unsigned char data) { struct pm860x_chip *chip = i2c_get_clientdata(i2c); - unsigned char value; + struct regmap *map = (i2c == chip->client) ? chip->regmap + : chip->regmap_companion; int ret; - mutex_lock(&chip->io_lock); - ret = pm860x_read_device(i2c, reg, 1, &value); - if (ret < 0) - goto out; - value &= ~mask; - value |= data; - ret = pm860x_write_device(i2c, reg, 1, &value); -out: - mutex_unlock(&chip->io_lock); + ret = regmap_update_bits(map, reg, mask, data); return ret; } EXPORT_SYMBOL(pm860x_set_bits); @@ -300,11 +259,17 @@ static int verify_addr(struct i2c_client *i2c) return 0; } +static struct regmap_config pm860x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + static int __devinit pm860x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pm860x_platform_data *pdata = client->dev.platform_data; struct pm860x_chip *chip; + int ret; if (!pdata) { pr_info("No platform data in %s!\n", __func__); @@ -316,10 +281,16 @@ static int __devinit pm860x_probe(struct i2c_client *client, return -ENOMEM; chip->id = verify_addr(client); + chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config); + if (IS_ERR(chip->regmap)) { + ret = PTR_ERR(chip->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } chip->client = client; i2c_set_clientdata(client, chip); chip->dev = &client->dev; - mutex_init(&chip->io_lock); dev_set_drvdata(chip->dev, chip); /* @@ -333,6 +304,14 @@ static int __devinit pm860x_probe(struct i2c_client *client, chip->companion_addr = pdata->companion_addr; chip->companion = i2c_new_dummy(chip->client->adapter, chip->companion_addr); + chip->regmap_companion = regmap_init_i2c(chip->companion, + &pm860x_regmap_config); + if (IS_ERR(chip->regmap_companion)) { + ret = PTR_ERR(chip->regmap_companion); + dev_err(&chip->companion->dev, + "Failed to allocate register map: %d\n", ret); + return ret; + } i2c_set_clientdata(chip->companion, chip); } @@ -345,7 +324,11 @@ static int __devexit pm860x_remove(struct i2c_client *client) struct pm860x_chip *chip = i2c_get_clientdata(client); pm860x_device_exit(chip); - i2c_unregister_device(chip->companion); + if (chip->companion) { + regmap_exit(chip->regmap_companion); + i2c_unregister_device(chip->companion); + } + regmap_exit(chip->regmap); kfree(chip); return 0; } diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f1391c21ef2..c9acd32fc0a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -12,6 +12,7 @@ config MFD_CORE config MFD_88PM860X bool "Support Marvell 88PM8606/88PM8607" depends on I2C=y && GENERIC_HARDIRQS + select REGMAP_I2C select MFD_CORE help This supports for Marvell 88PM8606/88PM8607 Power Management IC. diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index 63b4fb8e3b6..92be3476c9f 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -297,10 +297,11 @@ enum { struct pm860x_chip { struct device *dev; - struct mutex io_lock; struct mutex irq_lock; struct i2c_client *client; struct i2c_client *companion; /* companion chip client */ + struct regmap *regmap; + struct regmap *regmap_companion; int buck3_double; /* DVC ramp slope double */ unsigned short companion_addr; -- cgit v1.2.3-70-g09d2 From 2439d9714e8f4f106c8965e093f9892cfb347d76 Mon Sep 17 00:00:00 2001 From: Donggeun Kim Date: Thu, 24 Nov 2011 18:12:17 +0900 Subject: mfd: Add platform data for MAX8997 MUIC driver Currently, MAX8997 device does not support MUIC function of it. To add MAX8997 MUIC driver, header file should be updated. Signed-off-by: Donggeun Kim Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Signed-off-by: Samuel Ortiz --- include/linux/mfd/max8997.h | 58 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'include/linux/mfd') diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 0bbd13dbe33..49d2a0bfd7f 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -77,6 +77,60 @@ struct max8997_regulator_data { struct regulator_init_data *initdata; }; +enum max8997_muic_usb_type { + MAX8997_USB_HOST, + MAX8997_USB_DEVICE, +}; + +enum max8997_muic_charger_type { + MAX8997_CHARGER_TYPE_NONE = 0, + MAX8997_CHARGER_TYPE_USB, + MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT, + MAX8997_CHARGER_TYPE_DEDICATED_CHG, + MAX8997_CHARGER_TYPE_500MA, + MAX8997_CHARGER_TYPE_1A, + MAX8997_CHARGER_TYPE_DEAD_BATTERY = 7, +}; + +struct max8997_muic_reg_data { + u8 addr; + u8 data; +}; + +/** + * struct max8997_muic_platform_data + * @usb_callback: callback function for USB + * inform callee of USB type (HOST or DEVICE) + * and attached state(true or false) + * @charger_callback: callback function for charger + * inform callee of charger_type + * and attached state(true or false) + * @deskdock_callback: callback function for desk dock + * inform callee of attached state(true or false) + * @cardock_callback: callback function for car dock + * inform callee of attached state(true or false) + * @mhl_callback: callback function for MHL (Mobile High-definition Link) + * inform callee of attached state(true or false) + * @uart_callback: callback function for JIG UART + * inform callee of attached state(true or false) + * @init_data: array of max8997_muic_reg_data + * used for initializing registers of MAX8997 MUIC device + * @num_init_data: array size of init_data + */ +struct max8997_muic_platform_data { + void (*usb_callback)(enum max8997_muic_usb_type usb_type, + bool attached); + void (*charger_callback)(bool attached, + enum max8997_muic_charger_type charger_type); + void (*deskdock_callback) (bool attached); + void (*cardock_callback) (bool attached); + void (*mhl_callback) (bool attached); + void (*uart_callback) (bool attached); + + struct max8997_muic_reg_data *init_data; + int num_init_data; +}; + struct max8997_platform_data { /* IRQ */ int irq_base; @@ -113,7 +167,9 @@ struct max8997_platform_data { /* charge Full Timeout */ int timeout; /* 0 (no timeout), 5, 6, 7 hours */ - /* MUIC: Not implemented */ + /* ---- MUIC ---- */ + struct max8997_muic_platform_data *muic_pdata; + /* HAPTIC: Not implemented */ /* RTC: Not implemented */ /* Flash: Not implemented */ -- cgit v1.2.3-70-g09d2 From 2161891a0a7bcad6ee8819bb324ee4a031bc8a95 Mon Sep 17 00:00:00 2001 From: Robin van der Gracht Date: Tue, 29 Nov 2011 12:09:03 +0100 Subject: mfd: Fixed unconditional reset of the mc13xxx ADC reading enable bits When the ADC is being prepared for a single or multiple channel reading, the adc0 register is reconfigured without taking the lithium cell, charge current and battery current reading enable bits into account. Which results in clearing the bits. Signed-off-by: Robin van der Gracht Signed-off-by: Samuel Ortiz --- drivers/mfd/mc13xxx-core.c | 4 ++-- include/linux/mfd/mc13xxx.h | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'include/linux/mfd') diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 44173804845..d0d3dfafba5 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c @@ -615,13 +615,13 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, break; case MC13XXX_ADC_MODE_SINGLE_CHAN: - adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK; + adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT; adc1 |= MC13XXX_ADC1_RAND; break; case MC13XXX_ADC_MODE_MULT_CHAN: - adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK; + adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; break; diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h index 3816c2fac0a..261fc117b40 100644 --- a/include/linux/mfd/mc13xxx.h +++ b/include/linux/mfd/mc13xxx.h @@ -173,6 +173,9 @@ struct mc13xxx_platform_data { #define MC13XXX_ADC_MODE_MULT_CHAN 3 #define MC13XXX_ADC0 43 +#define MC13XXX_ADC0_LICELLCON (1 << 0) +#define MC13XXX_ADC0_CHRGICON (1 << 1) +#define MC13XXX_ADC0_BATICON (1 << 2) #define MC13XXX_ADC0_ADREFEN (1 << 10) #define MC13XXX_ADC0_TSMOD0 (1 << 12) #define MC13XXX_ADC0_TSMOD1 (1 << 13) @@ -184,4 +187,9 @@ struct mc13xxx_platform_data { MC13XXX_ADC0_TSMOD1 | \ MC13XXX_ADC0_TSMOD2) +#define MC13XXX_ADC0_CONFIG_MASK (MC13XXX_ADC0_TSMOD_MASK | \ + MC13XXX_ADC0_LICELLCON | \ + MC13XXX_ADC0_CHRGICON | \ + MC13XXX_ADC0_BATICON) + #endif /* ifndef __LINUX_MFD_MC13XXX_H */ -- cgit v1.2.3-70-g09d2 From 5dd7bf59e0e8563265b3e5b33276099ef628fcc7 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Sun, 27 Nov 2011 22:00:54 +0100 Subject: ARM: sa11x0: Implement autoloading of codec and codec pdata for mcp bus. Signed-off-by: Jochen Friedrich Signed-off-by: Samuel Ortiz --- arch/arm/mach-sa1100/assabet.c | 1 + arch/arm/mach-sa1100/cerf.c | 1 + arch/arm/mach-sa1100/collie.c | 8 +++++- arch/arm/mach-sa1100/include/mach/mcp.h | 2 ++ arch/arm/mach-sa1100/lart.c | 1 + arch/arm/mach-sa1100/shannon.c | 1 + arch/arm/mach-sa1100/simpad.c | 8 +++++- drivers/mfd/mcp-core.c | 44 ++++++++++++++++++++++++++++-- drivers/mfd/mcp-sa11x0.c | 7 +++-- drivers/mfd/ucb1x00-core.c | 48 +++++++++++++++++++++++++-------- drivers/mfd/ucb1x00-ts.c | 2 +- include/linux/mfd/mcp.h | 7 +++-- include/linux/mfd/ucb1x00.h | 5 +++- include/linux/mod_devicetable.h | 11 ++++++++ scripts/mod/file2alias.c | 13 +++++++++ 15 files changed, 138 insertions(+), 21 deletions(-) (limited to 'include/linux/mfd') diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 3dd133f1841..14b31f116ef 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -202,6 +202,7 @@ static struct irda_platform_data assabet_irda_data = { static struct mcp_plat_data assabet_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init assabet_init(void) diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 7f3da4b11ec..b7db7cd0830 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -124,6 +124,7 @@ static void __init cerf_map_io(void) static struct mcp_plat_data cerf_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init cerf_init(void) diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 2965cc9d424..b0b5efee683 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -85,10 +86,15 @@ static struct scoop_pcmcia_config collie_pcmcia_config = { .num_devs = 1, }; +static struct ucb1x00_plat_data collie_ucb1x00_data = { + .gpio_base = COLLIE_TC35143_GPIO_BASE, +}; + static struct mcp_plat_data collie_mcp_data = { .mccr0 = MCCR0_ADM | MCCR0_ExtClk, .sclk_rate = 9216000, - .gpio_base = COLLIE_TC35143_GPIO_BASE, + .codec = "ucb1x00", + .codec_pdata = &collie_ucb1x00_data, }; /* diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h index ed1a331508a..586cec898b3 100644 --- a/arch/arm/mach-sa1100/include/mach/mcp.h +++ b/arch/arm/mach-sa1100/include/mach/mcp.h @@ -17,6 +17,8 @@ struct mcp_plat_data { u32 mccr1; unsigned int sclk_rate; int gpio_base; + const char *codec; + void *codec_pdata; }; #endif diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 5bc59d0947b..34bbdd986e4 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -24,6 +24,7 @@ static struct mcp_plat_data lart_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init lart_init(void) diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index 1cccbf5b9e9..252faa5e239 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c @@ -55,6 +55,7 @@ static struct resource shannon_flash_resource = { static struct mcp_plat_data shannon_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init shannon_init(void) diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 4790f3f3d00..7eac8ebab94 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -187,10 +188,15 @@ static struct resource simpad_flash_resources [] = { } }; +static struct ucb1x00_plat_data simpad_ucb1x00_data = { + .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, +}; + static struct mcp_plat_data simpad_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, - .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, + .codec = "ucb1300", + .codec_pdata = &simpad_ucb1x00_data, }; diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 84815f9ef63..63be60bc345 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c @@ -26,9 +26,35 @@ #define to_mcp(d) container_of(d, struct mcp, attached_device) #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) +static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id, + const char *codec) +{ + while (id->name[0]) { + if (strcmp(codec, id->name) == 0) + return id; + id++; + } + return NULL; +} + +const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp) +{ + const struct mcp_driver *driver = + to_mcp_driver(mcp->attached_device.driver); + + return mcp_match_id(driver->id_table, mcp->codec); +} +EXPORT_SYMBOL(mcp_get_device_id); + static int mcp_bus_match(struct device *dev, struct device_driver *drv) { - return 1; + const struct mcp *mcp = to_mcp(dev); + const struct mcp_driver *driver = to_mcp_driver(drv); + + if (driver->id_table) + return !!mcp_match_id(driver->id_table, mcp->codec); + + return 0; } static int mcp_bus_probe(struct device *dev) @@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev) return ret; } +static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct mcp *mcp = to_mcp(dev); + + add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec); + return 0; +} + static struct bus_type mcp_bus_type = { .name = "mcp", .match = mcp_bus_match, + .uevent = mcp_bus_uevent, .probe = mcp_bus_probe, .remove = mcp_bus_remove, .suspend = mcp_bus_suspend, @@ -212,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) } EXPORT_SYMBOL(mcp_host_alloc); -int mcp_host_register(struct mcp *mcp) +int mcp_host_register(struct mcp *mcp, void *pdata) { + if (!mcp->codec) + return -EINVAL; + + mcp->attached_device.platform_data = pdata; dev_set_name(&mcp->attached_device, "mcp0"); + request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec); return device_register(&mcp->attached_device); } EXPORT_SYMBOL(mcp_host_register); diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 02c53a0766c..da4e077a1be 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c @@ -146,6 +146,9 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) if (!data) return -ENODEV; + if (!data->codec) + return -ENODEV; + if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) return -EBUSY; @@ -162,7 +165,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) mcp->dma_audio_wr = DMA_Ser4MCP0Wr; mcp->dma_telco_rd = DMA_Ser4MCP1Rd; mcp->dma_telco_wr = DMA_Ser4MCP1Wr; - mcp->gpio_base = data->gpio_base; + mcp->codec = data->codec; platform_set_drvdata(pdev, mcp); @@ -195,7 +198,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / mcp->sclk_rate; - ret = mcp_host_register(mcp); + ret = mcp_host_register(mcp, data->codec_pdata); if (ret == 0) goto out; diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index b281217334e..91c4f25e0e5 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c @@ -36,6 +36,15 @@ static DEFINE_MUTEX(ucb1x00_mutex); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_devices); +static struct mcp_device_id ucb1x00_id[] = { + { "ucb1x00", 0 }, /* auto-detection */ + { "ucb1200", UCB_ID_1200 }, + { "ucb1300", UCB_ID_1300 }, + { "tc35143", UCB_ID_TC35143 }, + { } +}; +MODULE_DEVICE_TABLE(mcp, ucb1x00_id); + /** * ucb1x00_io_set_dir - set IO direction * @ucb: UCB1x00 structure describing chip @@ -527,17 +536,33 @@ static struct class ucb1x00_class = { static int ucb1x00_probe(struct mcp *mcp) { + const struct mcp_device_id *mid; struct ucb1x00 *ucb; struct ucb1x00_driver *drv; + struct ucb1x00_plat_data *pdata; unsigned int id; int ret = -ENODEV; int temp; mcp_enable(mcp); id = mcp_reg_read(mcp, UCB_ID); + mid = mcp_get_device_id(mcp); - if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { - printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); + if (mid && mid->driver_data) { + if (id != mid->driver_data) { + printk(KERN_WARNING "%s wrong ID %04x found: %04x\n", + mid->name, (unsigned int) mid->driver_data, id); + goto err_disable; + } + } else { + mid = &ucb1x00_id[1]; + while (mid->driver_data) { + if (id == mid->driver_data) + break; + mid++; + } + printk(KERN_WARNING "%s ID not found: %04x\n", + ucb1x00_id[0].name, id); goto err_disable; } @@ -546,28 +571,28 @@ static int ucb1x00_probe(struct mcp *mcp) if (!ucb) goto err_disable; - + pdata = mcp->attached_device.platform_data; ucb->dev.class = &ucb1x00_class; ucb->dev.parent = &mcp->attached_device; - dev_set_name(&ucb->dev, "ucb1x00"); + dev_set_name(&ucb->dev, mid->name); spin_lock_init(&ucb->lock); spin_lock_init(&ucb->io_lock); sema_init(&ucb->adc_sem, 1); - ucb->id = id; + ucb->id = mid; ucb->mcp = mcp; ucb->irq = ucb1x00_detect_irq(ucb); if (ucb->irq == NO_IRQ) { - printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); + printk(KERN_ERR "%s: IRQ probe failed\n", mid->name); ret = -ENODEV; goto err_free; } ucb->gpio.base = -1; - if (mcp->gpio_base != 0) { + if (pdata && (pdata->gpio_base >= 0)) { ucb->gpio.label = dev_name(&ucb->dev); - ucb->gpio.base = mcp->gpio_base; + ucb->gpio.base = pdata->gpio_base; ucb->gpio.ngpio = 10; ucb->gpio.set = ucb1x00_gpio_set; ucb->gpio.get = ucb1x00_gpio_get; @@ -580,10 +605,10 @@ static int ucb1x00_probe(struct mcp *mcp) dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, - "UCB1x00", ucb); + mid->name, ucb); if (ret) { - printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", - ucb->irq, ret); + printk(KERN_ERR "%s: unable to grab irq%d: %d\n", + mid->name, ucb->irq, ret); goto err_gpio; } @@ -705,6 +730,7 @@ static struct mcp_driver ucb1x00_driver = { .remove = ucb1x00_remove, .suspend = ucb1x00_suspend, .resume = ucb1x00_resume, + .id_table = ucb1x00_id, }; static int __init ucb1x00_init(void) diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 38ffbd50a0d..40ec3c11886 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -382,7 +382,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; idev->name = "Touchscreen panel"; - idev->id.product = ts->ucb->id; + idev->id.product = ts->ucb->id->driver_data; idev->open = ucb1x00_ts_open; idev->close = ucb1x00_ts_close; diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h index ee496708e38..1515e64e366 100644 --- a/include/linux/mfd/mcp.h +++ b/include/linux/mfd/mcp.h @@ -10,6 +10,7 @@ #ifndef MCP_H #define MCP_H +#include #include struct mcp_ops; @@ -26,7 +27,7 @@ struct mcp { dma_device_t dma_telco_rd; dma_device_t dma_telco_wr; struct device attached_device; - int gpio_base; + const char *codec; }; struct mcp_ops { @@ -44,10 +45,11 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int); unsigned int mcp_reg_read(struct mcp *, unsigned int); void mcp_enable(struct mcp *); void mcp_disable(struct mcp *); +const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp); #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) struct mcp *mcp_host_alloc(struct device *, size_t); -int mcp_host_register(struct mcp *); +int mcp_host_register(struct mcp *, void *); void mcp_host_unregister(struct mcp *); struct mcp_driver { @@ -56,6 +58,7 @@ struct mcp_driver { void (*remove)(struct mcp *); int (*suspend)(struct mcp *, pm_message_t); int (*resume)(struct mcp *); + const struct mcp_device_id *id_table; }; int mcp_driver_register(struct mcp_driver *); diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index 4321f044d1e..bc19e5fb7ea 100644 --- a/include/linux/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h @@ -104,6 +104,9 @@ #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) #define UCB_MODE_AUD_OFF_CAN (1 << 13) +struct ucb1x00_plat_data { + int gpio_base; +}; struct ucb1x00_irq { void *devid; @@ -116,7 +119,7 @@ struct ucb1x00 { unsigned int irq; struct semaphore adc_sem; spinlock_t io_lock; - u16 id; + const struct mcp_device_id *id; u16 io_dir; u16 io_out; u16 adc_cr; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 468819cdde8..bc50d9a80d8 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -436,6 +436,17 @@ struct spi_device_id { __attribute__((aligned(sizeof(kernel_ulong_t)))); }; +/* mcp */ + +#define MCP_NAME_SIZE 20 +#define MCP_MODULE_PREFIX "mcp:" + +struct mcp_device_id { + char name[MCP_NAME_SIZE]; + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + /* dmi */ enum dmi_field { DMI_NONE, diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index f936d1fa969..e8c7eb16c0e 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -774,6 +774,15 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, return 1; } +/* Looks like: mcp:S */ +static int do_mcp_entry(const char *filename, struct mcp_device_id *id, + char *alias) +{ + sprintf(alias, MCP_MODULE_PREFIX "%s", id->name); + + return 1; +} + static const struct dmifield { const char *prefix; int field; @@ -1027,6 +1036,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct spi_device_id), "spi", do_spi_entry, mod); + else if (sym_is(symname, "__mod_mcp_device_table")) + do_table(symval, sym->st_size, + sizeof(struct mcp_device_id), "mcp", + do_mcp_entry, mod); else if (sym_is(symname, "__mod_dmi_device_table")) do_table(symval, sym->st_size, sizeof(struct dmi_system_id), "dmi", -- cgit v1.2.3-70-g09d2 From bdd6a67a3936f4da5ef382ec640b8d1eb1f209fa Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 28 Nov 2011 23:26:47 +0000 Subject: mfd: Constify WM8994 regulator_init_data The driver has no need to modify the regulator_init_data so declare it const to allow machine code to do so. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- include/linux/mfd/wm8994/pdata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/mfd') diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 54e2fef587d..b00897a6c46 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -23,7 +23,7 @@ struct wm8994_ldo_pdata { int enable; const char *supply; - struct regulator_init_data *init_data; + const struct regulator_init_data *init_data; }; #define WM8994_CONFIGURE_GPIO 0x10000 -- cgit v1.2.3-70-g09d2 From 83051b7287e43241ccb6adaaa92615a87274898b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 1 Dec 2011 13:56:53 +0000 Subject: mfd: Add missing mutex.h inclusion to WM8994 core.h struct wm8994 includes a mutex so we need to include mutex.h before we declare it. All current users rely on this being done implicitly. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- include/linux/mfd/wm8994/core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/mfd') diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index f44bdb7273b..8eb1b75cb75 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h @@ -15,6 +15,7 @@ #ifndef __MFD_WM8994_CORE_H__ #define __MFD_WM8994_CORE_H__ +#include #include enum wm8994_type { -- cgit v1.2.3-70-g09d2 From ee66e653ca7425bc8ffca4e00f19a8057cd14e4d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 2 Dec 2011 14:16:33 +0100 Subject: mfd: Unify abx500 headers in mfd/abx500 This moves all the header files related to the abx500 family into a common include directory below mfd. From now on we place any subchip header in that directory. Headers previously in e.g. get prefixed and are now e.g. . The top-level abstract interface remains in . Signed-off-by: Linus Walleij Signed-off-by: Samuel Ortiz --- arch/arm/mach-ux500/board-mop500.c | 4 +- arch/arm/mach-ux500/board-u5500.c | 2 +- .../mach-ux500/include/mach/irqs-board-mop500.h | 2 +- drivers/input/misc/ab8500-ponkey.c | 2 +- drivers/mfd/ab5500-core.c | 2 +- drivers/mfd/ab5500-debugfs.c | 2 +- drivers/mfd/ab8500-core.c | 2 +- drivers/mfd/ab8500-debugfs.c | 2 +- drivers/mfd/ab8500-gpadc.c | 4 +- drivers/mfd/ab8500-i2c.c | 2 +- drivers/mfd/ab8500-sysctrl.c | 4 +- drivers/misc/ab8500-pwm.c | 2 +- drivers/regulator/ab8500.c | 2 +- drivers/rtc/rtc-ab8500.c | 2 +- drivers/usb/otg/ab8500-usb.c | 2 +- include/linux/mfd/ab5500/ab5500.h | 140 ------------ include/linux/mfd/ab8500.h | 201 ---------------- include/linux/mfd/ab8500/gpadc.h | 35 --- include/linux/mfd/ab8500/gpio.h | 21 -- include/linux/mfd/ab8500/sysctrl.h | 254 --------------------- include/linux/mfd/abx500/ab5500.h | 140 ++++++++++++ include/linux/mfd/abx500/ab8500-gpadc.h | 35 +++ include/linux/mfd/abx500/ab8500-gpio.h | 21 ++ include/linux/mfd/abx500/ab8500-sysctrl.h | 254 +++++++++++++++++++++ include/linux/mfd/abx500/ab8500.h | 201 ++++++++++++++++ 25 files changed, 669 insertions(+), 669 deletions(-) delete mode 100644 include/linux/mfd/ab5500/ab5500.h delete mode 100644 include/linux/mfd/ab8500.h delete mode 100644 include/linux/mfd/ab8500/gpadc.h delete mode 100644 include/linux/mfd/ab8500/gpio.h delete mode 100644 include/linux/mfd/ab8500/sysctrl.h create mode 100644 include/linux/mfd/abx500/ab5500.h create mode 100644 include/linux/mfd/abx500/ab8500-gpadc.h create mode 100644 include/linux/mfd/abx500/ab8500-gpio.h create mode 100644 include/linux/mfd/abx500/ab8500-sysctrl.h create mode 100644 include/linux/mfd/abx500/ab8500.h (limited to 'include/linux/mfd') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index bdd7b80dd7a..80cef36d71c 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -19,11 +19,11 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 82025ba70c0..4ecb07a93f1 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h index 47969909836..d2d4131435a 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h @@ -9,7 +9,7 @@ #define __MACH_IRQS_BOARD_MOP500_H /* Number of AB8500 irqs is taken from header file */ -#include +#include #define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START #define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \ diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 3d3288a78fd..3f199e1539b 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include /** diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c index ec10629a0b0..bd56a764dea 100644 --- a/drivers/mfd/ab5500-core.c +++ b/drivers/mfd/ab5500-core.c @@ -22,8 +22,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c index b7b2d3483fd..72006940937 100644 --- a/drivers/mfd/ab5500-debugfs.c +++ b/drivers/mfd/ab5500-debugfs.c @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #include #include "ab5500-core.h" diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index d3d572b2317..53e2a80f42f 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include /* diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index dedb7f65cea..9a0211aa889 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -13,7 +13,7 @@ #include #include -#include +#include static u32 debug_bank; static u32 debug_address; diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index e985d1701a8..c39fc716e1d 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -18,9 +18,9 @@ #include #include #include -#include #include -#include +#include +#include /* * GPADC register offsets diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c index 9be541c6b00..087fecd71ce 100644 --- a/drivers/mfd/ab8500-i2c.c +++ b/drivers/mfd/ab8500-i2c.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index f20feefac19..c28d4eb1eff 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -7,9 +7,9 @@ #include #include #include -#include #include -#include +#include +#include static struct device *sysctrl_dev; diff --git a/drivers/misc/ab8500-pwm.c b/drivers/misc/ab8500-pwm.c index 2208a9d5262..d7a9aa14e5d 100644 --- a/drivers/misc/ab8500-pwm.c +++ b/drivers/misc/ab8500-pwm.c @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include /* diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 6e1ae69646b..80d08237a5a 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -16,8 +16,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index e346705aae9..db16ce212d6 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #define AB8500_RTC_SOFF_STAT_REG 0x00 diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index 07ccea9ada4..74fe6e62e0f 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #define AB8500_MAIN_WD_CTRL_REG 0x01 #define AB8500_USB_LINE_STAT_REG 0x80 diff --git a/include/linux/mfd/ab5500/ab5500.h b/include/linux/mfd/ab5500/ab5500.h deleted file mode 100644 index a720051ae93..00000000000 --- a/include/linux/mfd/ab5500/ab5500.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) ST-Ericsson 2011 - * - * License Terms: GNU General Public License v2 - */ -#ifndef MFD_AB5500_H -#define MFD_AB5500_H - -#include - -enum ab5500_devid { - AB5500_DEVID_ADC, - AB5500_DEVID_LEDS, - AB5500_DEVID_POWER, - AB5500_DEVID_REGULATORS, - AB5500_DEVID_SIM, - AB5500_DEVID_RTC, - AB5500_DEVID_CHARGER, - AB5500_DEVID_FUELGAUGE, - AB5500_DEVID_VIBRATOR, - AB5500_DEVID_CODEC, - AB5500_DEVID_USB, - AB5500_DEVID_OTP, - AB5500_DEVID_VIDEO, - AB5500_DEVID_DBIECI, - AB5500_DEVID_ONSWA, - AB5500_NUM_DEVICES, -}; - -enum ab5500_banks { - AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP = 0, - AB5500_BANK_VDDDIG_IO_I2C_CLK_TST = 1, - AB5500_BANK_VDENC = 2, - AB5500_BANK_SIM_USBSIM = 3, - AB5500_BANK_LED = 4, - AB5500_BANK_ADC = 5, - AB5500_BANK_RTC = 6, - AB5500_BANK_STARTUP = 7, - AB5500_BANK_DBI_ECI = 8, - AB5500_BANK_CHG = 9, - AB5500_BANK_FG_BATTCOM_ACC = 10, - AB5500_BANK_USB = 11, - AB5500_BANK_IT = 12, - AB5500_BANK_VIBRA = 13, - AB5500_BANK_AUDIO_HEADSETUSB = 14, - AB5500_NUM_BANKS = 15, -}; - -enum ab5500_banks_addr { - AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP = 0x4A, - AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST = 0x4B, - AB5500_ADDR_VDENC = 0x06, - AB5500_ADDR_SIM_USBSIM = 0x04, - AB5500_ADDR_LED = 0x10, - AB5500_ADDR_ADC = 0x0A, - AB5500_ADDR_RTC = 0x0F, - AB5500_ADDR_STARTUP = 0x03, - AB5500_ADDR_DBI_ECI = 0x07, - AB5500_ADDR_CHG = 0x0B, - AB5500_ADDR_FG_BATTCOM_ACC = 0x0C, - AB5500_ADDR_USB = 0x05, - AB5500_ADDR_IT = 0x0E, - AB5500_ADDR_VIBRA = 0x02, - AB5500_ADDR_AUDIO_HEADSETUSB = 0x0D, -}; - -/* - * Interrupt register offsets - * Bank : 0x0E - */ -#define AB5500_IT_SOURCE0_REG 0x20 -#define AB5500_IT_SOURCE1_REG 0x21 -#define AB5500_IT_SOURCE2_REG 0x22 -#define AB5500_IT_SOURCE3_REG 0x23 -#define AB5500_IT_SOURCE4_REG 0x24 -#define AB5500_IT_SOURCE5_REG 0x25 -#define AB5500_IT_SOURCE6_REG 0x26 -#define AB5500_IT_SOURCE7_REG 0x27 -#define AB5500_IT_SOURCE8_REG 0x28 -#define AB5500_IT_SOURCE9_REG 0x29 -#define AB5500_IT_SOURCE10_REG 0x2A -#define AB5500_IT_SOURCE11_REG 0x2B -#define AB5500_IT_SOURCE12_REG 0x2C -#define AB5500_IT_SOURCE13_REG 0x2D -#define AB5500_IT_SOURCE14_REG 0x2E -#define AB5500_IT_SOURCE15_REG 0x2F -#define AB5500_IT_SOURCE16_REG 0x30 -#define AB5500_IT_SOURCE17_REG 0x31 -#define AB5500_IT_SOURCE18_REG 0x32 -#define AB5500_IT_SOURCE19_REG 0x33 -#define AB5500_IT_SOURCE20_REG 0x34 -#define AB5500_IT_SOURCE21_REG 0x35 -#define AB5500_IT_SOURCE22_REG 0x36 -#define AB5500_IT_SOURCE23_REG 0x37 - -#define AB5500_NUM_IRQ_REGS 23 - -/** - * struct ab5500 - * @access_mutex: lock out concurrent accesses to the AB registers - * @dev: a pointer to the device struct for this chip driver - * @ab5500_irq: the analog baseband irq - * @irq_base: the platform configuration irq base for subdevices - * @chip_name: name of this chip variant - * @chip_id: 8 bit chip ID for this chip variant - * @irq_lock: a lock to protect the mask - * @abb_events: a local bit mask of the prcmu wakeup events - * @event_mask: a local copy of the mask event registers - * @last_event_mask: a copy of the last event_mask written to hardware - * @startup_events: a copy of the first reading of the event registers - * @startup_events_read: whether the first events have been read - */ -struct ab5500 { - struct mutex access_mutex; - struct device *dev; - unsigned int ab5500_irq; - unsigned int irq_base; - char chip_name[32]; - u8 chip_id; - struct mutex irq_lock; - u32 abb_events; - u8 mask[AB5500_NUM_IRQ_REGS]; - u8 oldmask[AB5500_NUM_IRQ_REGS]; - u8 startup_events[AB5500_NUM_IRQ_REGS]; - bool startup_events_read; -#ifdef CONFIG_DEBUG_FS - unsigned int debug_bank; - unsigned int debug_address; -#endif -}; - -struct ab5500_platform_data { - struct {unsigned int base; unsigned int count; } irq; - void *dev_data[AB5500_NUM_DEVICES]; - struct abx500_init_settings *init_settings; - unsigned int init_settings_sz; - bool pm_power_off; -}; - -#endif /* MFD_AB5500_H */ diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h deleted file mode 100644 index 838c6b487cc..00000000000 --- a/include/linux/mfd/ab8500.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License v2 - * Author: Srinidhi Kasagar - */ -#ifndef MFD_AB8500_H -#define MFD_AB8500_H - -#include - -/* - * AB8500 bank addresses - */ -#define AB8500_SYS_CTRL1_BLOCK 0x1 -#define AB8500_SYS_CTRL2_BLOCK 0x2 -#define AB8500_REGU_CTRL1 0x3 -#define AB8500_REGU_CTRL2 0x4 -#define AB8500_USB 0x5 -#define AB8500_TVOUT 0x6 -#define AB8500_DBI 0x7 -#define AB8500_ECI_AV_ACC 0x8 -#define AB8500_RESERVED 0x9 -#define AB8500_GPADC 0xA -#define AB8500_CHARGER 0xB -#define AB8500_GAS_GAUGE 0xC -#define AB8500_AUDIO 0xD -#define AB8500_INTERRUPT 0xE -#define AB8500_RTC 0xF -#define AB8500_MISC 0x10 -#define AB8500_DEVELOPMENT 0x11 -#define AB8500_DEBUG 0x12 -#define AB8500_PROD_TEST 0x13 -#define AB8500_OTP_EMUL 0x15 - -/* - * Interrupts - */ - -#define AB8500_INT_MAIN_EXT_CH_NOT_OK 0 -#define AB8500_INT_UN_PLUG_TV_DET 1 -#define AB8500_INT_PLUG_TV_DET 2 -#define AB8500_INT_TEMP_WARM 3 -#define AB8500_INT_PON_KEY2DB_F 4 -#define AB8500_INT_PON_KEY2DB_R 5 -#define AB8500_INT_PON_KEY1DB_F 6 -#define AB8500_INT_PON_KEY1DB_R 7 -#define AB8500_INT_BATT_OVV 8 -#define AB8500_INT_MAIN_CH_UNPLUG_DET 10 -#define AB8500_INT_MAIN_CH_PLUG_DET 11 -#define AB8500_INT_USB_ID_DET_F 12 -#define AB8500_INT_USB_ID_DET_R 13 -#define AB8500_INT_VBUS_DET_F 14 -#define AB8500_INT_VBUS_DET_R 15 -#define AB8500_INT_VBUS_CH_DROP_END 16 -#define AB8500_INT_RTC_60S 17 -#define AB8500_INT_RTC_ALARM 18 -#define AB8500_INT_BAT_CTRL_INDB 20 -#define AB8500_INT_CH_WD_EXP 21 -#define AB8500_INT_VBUS_OVV 22 -#define AB8500_INT_MAIN_CH_DROP_END 23 -#define AB8500_INT_CCN_CONV_ACC 24 -#define AB8500_INT_INT_AUD 25 -#define AB8500_INT_CCEOC 26 -#define AB8500_INT_CC_INT_CALIB 27 -#define AB8500_INT_LOW_BAT_F 28 -#define AB8500_INT_LOW_BAT_R 29 -#define AB8500_INT_BUP_CHG_NOT_OK 30 -#define AB8500_INT_BUP_CHG_OK 31 -#define AB8500_INT_GP_HW_ADC_CONV_END 32 -#define AB8500_INT_ACC_DETECT_1DB_F 33 -#define AB8500_INT_ACC_DETECT_1DB_R 34 -#define AB8500_INT_ACC_DETECT_22DB_F 35 -#define AB8500_INT_ACC_DETECT_22DB_R 36 -#define AB8500_INT_ACC_DETECT_21DB_F 37 -#define AB8500_INT_ACC_DETECT_21DB_R 38 -#define AB8500_INT_GP_SW_ADC_CONV_END 39 -#define AB8500_INT_GPIO6R 40 -#define AB8500_INT_GPIO7R 41 -#define AB8500_INT_GPIO8R 42 -#define AB8500_INT_GPIO9R 43 -#define AB8500_INT_GPIO10R 44 -#define AB8500_INT_GPIO11R 45 -#define AB8500_INT_GPIO12R 46 -#define AB8500_INT_GPIO13R 47 -#define AB8500_INT_GPIO24R 48 -#define AB8500_INT_GPIO25R 49 -#define AB8500_INT_GPIO36R 50 -#define AB8500_INT_GPIO37R 51 -#define AB8500_INT_GPIO38R 52 -#define AB8500_INT_GPIO39R 53 -#define AB8500_INT_GPIO40R 54 -#define AB8500_INT_GPIO41R 55 -#define AB8500_INT_GPIO6F 56 -#define AB8500_INT_GPIO7F 57 -#define AB8500_INT_GPIO8F 58 -#define AB8500_INT_GPIO9F 59 -#define AB8500_INT_GPIO10F 60 -#define AB8500_INT_GPIO11F 61 -#define AB8500_INT_GPIO12F 62 -#define AB8500_INT_GPIO13F 63 -#define AB8500_INT_GPIO24F 64 -#define AB8500_INT_GPIO25F 65 -#define AB8500_INT_GPIO36F 66 -#define AB8500_INT_GPIO37F 67 -#define AB8500_INT_GPIO38F 68 -#define AB8500_INT_GPIO39F 69 -#define AB8500_INT_GPIO40F 70 -#define AB8500_INT_GPIO41F 71 -#define AB8500_INT_ADP_SOURCE_ERROR 72 -#define AB8500_INT_ADP_SINK_ERROR 73 -#define AB8500_INT_ADP_PROBE_PLUG 74 -#define AB8500_INT_ADP_PROBE_UNPLUG 75 -#define AB8500_INT_ADP_SENSE_OFF 76 -#define AB8500_INT_USB_PHY_POWER_ERR 78 -#define AB8500_INT_USB_LINK_STATUS 79 -#define AB8500_INT_BTEMP_LOW 80 -#define AB8500_INT_BTEMP_LOW_MEDIUM 81 -#define AB8500_INT_BTEMP_MEDIUM_HIGH 82 -#define AB8500_INT_BTEMP_HIGH 83 -#define AB8500_INT_USB_CHARGER_NOT_OK 89 -#define AB8500_INT_ID_WAKEUP_R 90 -#define AB8500_INT_ID_DET_R1R 92 -#define AB8500_INT_ID_DET_R2R 93 -#define AB8500_INT_ID_DET_R3R 94 -#define AB8500_INT_ID_DET_R4R 95 -#define AB8500_INT_ID_WAKEUP_F 96 -#define AB8500_INT_ID_DET_R1F 98 -#define AB8500_INT_ID_DET_R2F 99 -#define AB8500_INT_ID_DET_R3F 100 -#define AB8500_INT_ID_DET_R4F 101 -#define AB8500_INT_USB_CHG_DET_DONE 102 -#define AB8500_INT_USB_CH_TH_PROT_F 104 -#define AB8500_INT_USB_CH_TH_PROT_R 105 -#define AB8500_INT_MAIN_CH_TH_PROT_F 106 -#define AB8500_INT_MAIN_CH_TH_PROT_R 107 -#define AB8500_INT_USB_CHARGER_NOT_OKF 111 - -#define AB8500_NR_IRQS 112 -#define AB8500_NUM_IRQ_REGS 14 - -/** - * struct ab8500 - ab8500 internal structure - * @dev: parent device - * @lock: read/write operations lock - * @irq_lock: genirq bus lock - * @irq: irq line - * @chip_id: chip revision id - * @write: register write - * @read: register read - * @rx_buf: rx buf for SPI - * @tx_buf: tx buf for SPI - * @mask: cache of IRQ regs for bus lock - * @oldmask: cache of previous IRQ regs for bus lock - */ -struct ab8500 { - struct device *dev; - struct mutex lock; - struct mutex irq_lock; - - int irq_base; - int irq; - u8 chip_id; - - int (*write) (struct ab8500 *a8500, u16 addr, u8 data); - int (*read) (struct ab8500 *a8500, u16 addr); - - unsigned long tx_buf[4]; - unsigned long rx_buf[4]; - - u8 mask[AB8500_NUM_IRQ_REGS]; - u8 oldmask[AB8500_NUM_IRQ_REGS]; -}; - -struct regulator_reg_init; -struct regulator_init_data; -struct ab8500_gpio_platform_data; - -/** - * struct ab8500_platform_data - AB8500 platform data - * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used - * @init: board-specific initialization after detection of ab8500 - * @num_regulator_reg_init: number of regulator init registers - * @regulator_reg_init: regulator init registers - * @num_regulator: number of regulators - * @regulator: machine-specific constraints for regulators - */ -struct ab8500_platform_data { - int irq_base; - void (*init) (struct ab8500 *); - int num_regulator_reg_init; - struct ab8500_regulator_reg_init *regulator_reg_init; - int num_regulator; - struct regulator_init_data *regulator; - struct ab8500_gpio_platform_data *gpio; -}; - -extern int __devinit ab8500_init(struct ab8500 *ab8500); -extern int __devexit ab8500_exit(struct ab8500 *ab8500); - -#endif /* MFD_AB8500_H */ diff --git a/include/linux/mfd/ab8500/gpadc.h b/include/linux/mfd/ab8500/gpadc.h deleted file mode 100644 index 252966769d9..00000000000 --- a/include/linux/mfd/ab8500/gpadc.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010 ST-Ericsson SA - * Licensed under GPLv2. - * - * Author: Arun R Murthy - * Author: Daniel Willerud - */ - -#ifndef _AB8500_GPADC_H -#define _AB8500_GPADC_H - -/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2) */ -#define BAT_CTRL 0x01 -#define BTEMP_BALL 0x02 -#define MAIN_CHARGER_V 0x03 -#define ACC_DETECT1 0x04 -#define ACC_DETECT2 0x05 -#define ADC_AUX1 0x06 -#define ADC_AUX2 0x07 -#define MAIN_BAT_V 0x08 -#define VBUS_V 0x09 -#define MAIN_CHARGER_C 0x0A -#define USB_CHARGER_C 0x0B -#define BK_BAT_V 0x0C -#define DIE_TEMP 0x0D - -struct ab8500_gpadc; - -struct ab8500_gpadc *ab8500_gpadc_get(char *name); -int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel); -int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel); -int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, - u8 channel, int ad_value); - -#endif /* _AB8500_GPADC_H */ diff --git a/include/linux/mfd/ab8500/gpio.h b/include/linux/mfd/ab8500/gpio.h deleted file mode 100644 index 488a8c920a2..00000000000 --- a/include/linux/mfd/ab8500/gpio.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright ST-Ericsson 2010. - * - * Author: Bibek Basu - * Licensed under GPLv2. - */ - -#ifndef _AB8500_GPIO_H -#define _AB8500_GPIO_H - -/* - * Platform data to register a block: only the initial gpio/irq number. - */ - -struct ab8500_gpio_platform_data { - int gpio_base; - u32 irq_base; - u8 config_reg[7]; -}; - -#endif /* _AB8500_GPIO_H */ diff --git a/include/linux/mfd/ab8500/sysctrl.h b/include/linux/mfd/ab8500/sysctrl.h deleted file mode 100644 index 10da0291f8f..00000000000 --- a/include/linux/mfd/ab8500/sysctrl.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * Author: Mattias Nilsson for ST Ericsson. - * License terms: GNU General Public License (GPL) version 2 - */ -#ifndef __AB8500_SYSCTRL_H -#define __AB8500_SYSCTRL_H - -#include - -#ifdef CONFIG_AB8500_CORE - -int ab8500_sysctrl_read(u16 reg, u8 *value); -int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value); - -#else - -static inline int ab8500_sysctrl_read(u16 reg, u8 *value) -{ - return 0; -} - -static inline int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) -{ - return 0; -} - -#endif /* CONFIG_AB8500_CORE */ - -static inline int ab8500_sysctrl_set(u16 reg, u8 bits) -{ - return ab8500_sysctrl_write(reg, bits, bits); -} - -static inline int ab8500_sysctrl_clear(u16 reg, u8 bits) -{ - return ab8500_sysctrl_write(reg, bits, 0); -} - -/* Registers */ -#define AB8500_TURNONSTATUS 0x100 -#define AB8500_RESETSTATUS 0x101 -#define AB8500_PONKEY1PRESSSTATUS 0x102 -#define AB8500_SYSCLKREQSTATUS 0x142 -#define AB8500_STW4500CTRL1 0x180 -#define AB8500_STW4500CTRL2 0x181 -#define AB8500_STW4500CTRL3 0x200 -#define AB8500_MAINWDOGCTRL 0x201 -#define AB8500_MAINWDOGTIMER 0x202 -#define AB8500_LOWBAT 0x203 -#define AB8500_BATTOK 0x204 -#define AB8500_SYSCLKTIMER 0x205 -#define AB8500_SMPSCLKCTRL 0x206 -#define AB8500_SMPSCLKSEL1 0x207 -#define AB8500_SMPSCLKSEL2 0x208 -#define AB8500_SMPSCLKSEL3 0x209 -#define AB8500_SYSULPCLKCONF 0x20A -#define AB8500_SYSULPCLKCTRL1 0x20B -#define AB8500_SYSCLKCTRL 0x20C -#define AB8500_SYSCLKREQ1VALID 0x20D -#define AB8500_SYSTEMCTRLSUP 0x20F -#define AB8500_SYSCLKREQ1RFCLKBUF 0x210 -#define AB8500_SYSCLKREQ2RFCLKBUF 0x211 -#define AB8500_SYSCLKREQ3RFCLKBUF 0x212 -#define AB8500_SYSCLKREQ4RFCLKBUF 0x213 -#define AB8500_SYSCLKREQ5RFCLKBUF 0x214 -#define AB8500_SYSCLKREQ6RFCLKBUF 0x215 -#define AB8500_SYSCLKREQ7RFCLKBUF 0x216 -#define AB8500_SYSCLKREQ8RFCLKBUF 0x217 -#define AB8500_DITHERCLKCTRL 0x220 -#define AB8500_SWATCTRL 0x230 -#define AB8500_HIQCLKCTRL 0x232 -#define AB8500_VSIMSYSCLKCTRL 0x233 - -/* Bits */ -#define AB8500_TURNONSTATUS_PORNVBAT BIT(0) -#define AB8500_TURNONSTATUS_PONKEY1DBF BIT(1) -#define AB8500_TURNONSTATUS_PONKEY2DBF BIT(2) -#define AB8500_TURNONSTATUS_RTCALARM BIT(3) -#define AB8500_TURNONSTATUS_MAINCHDET BIT(4) -#define AB8500_TURNONSTATUS_VBUSDET BIT(5) -#define AB8500_TURNONSTATUS_USBIDDETECT BIT(6) - -#define AB8500_RESETSTATUS_RESETN4500NSTATUS BIT(0) -#define AB8500_RESETSTATUS_SWRESETN4500NSTATUS BIT(2) - -#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_MASK 0x7F -#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_SHIFT 0 - -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ1STATUS BIT(0) -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ2STATUS BIT(1) -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ3STATUS BIT(2) -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ4STATUS BIT(3) -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ5STATUS BIT(4) -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ6STATUS BIT(5) -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ7STATUS BIT(6) -#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ8STATUS BIT(7) - -#define AB8500_STW4500CTRL1_SWOFF BIT(0) -#define AB8500_STW4500CTRL1_SWRESET4500N BIT(1) -#define AB8500_STW4500CTRL1_THDB8500SWOFF BIT(2) - -#define AB8500_STW4500CTRL2_RESETNVAUX1VALID BIT(0) -#define AB8500_STW4500CTRL2_RESETNVAUX2VALID BIT(1) -#define AB8500_STW4500CTRL2_RESETNVAUX3VALID BIT(2) -#define AB8500_STW4500CTRL2_RESETNVMODVALID BIT(3) -#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY1VALID BIT(4) -#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY2VALID BIT(5) -#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY3VALID BIT(6) -#define AB8500_STW4500CTRL2_RESETNVSMPS1VALID BIT(7) - -#define AB8500_STW4500CTRL3_CLK32KOUT2DIS BIT(0) -#define AB8500_STW4500CTRL3_RESETAUDN BIT(1) -#define AB8500_STW4500CTRL3_RESETDENCN BIT(2) -#define AB8500_STW4500CTRL3_THSDENA BIT(3) - -#define AB8500_MAINWDOGCTRL_MAINWDOGENA BIT(0) -#define AB8500_MAINWDOGCTRL_MAINWDOGKICK BIT(1) -#define AB8500_MAINWDOGCTRL_WDEXPTURNONVALID BIT(4) - -#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_MASK 0x7F -#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_SHIFT 0 - -#define AB8500_LOWBAT_LOWBATENA BIT(0) -#define AB8500_LOWBAT_LOWBAT_MASK 0x7E -#define AB8500_LOWBAT_LOWBAT_SHIFT 1 - -#define AB8500_BATTOK_BATTOKSEL0THF_MASK 0x0F -#define AB8500_BATTOK_BATTOKSEL0THF_SHIFT 0 -#define AB8500_BATTOK_BATTOKSEL1THF_MASK 0xF0 -#define AB8500_BATTOK_BATTOKSEL1THF_SHIFT 4 - -#define AB8500_SYSCLKTIMER_SYSCLKTIMER_MASK 0x0F -#define AB8500_SYSCLKTIMER_SYSCLKTIMER_SHIFT 0 -#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_MASK 0xF0 -#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_SHIFT 4 - -#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_MASK 0x03 -#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_SHIFT 0 -#define AB8500_SMPSCLKCTRL_3M2CLKINTENA BIT(2) - -#define AB8500_SMPSCLKSEL1_VARMCLKSEL_MASK 0x07 -#define AB8500_SMPSCLKSEL1_VARMCLKSEL_SHIFT 0 -#define AB8500_SMPSCLKSEL1_VAPECLKSEL_MASK 0x38 -#define AB8500_SMPSCLKSEL1_VAPECLKSEL_SHIFT 3 - -#define AB8500_SMPSCLKSEL2_VMODCLKSEL_MASK 0x07 -#define AB8500_SMPSCLKSEL2_VMODCLKSEL_SHIFT 0 -#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_MASK 0x38 -#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_SHIFT 3 - -#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_MASK 0x07 -#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_SHIFT 0 -#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_MASK 0x38 -#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_SHIFT 3 - -#define AB8500_SYSULPCLKCONF_ULPCLKCONF_MASK 0x03 -#define AB8500_SYSULPCLKCONF_ULPCLKCONF_SHIFT 0 -#define AB8500_SYSULPCLKCONF_CLK27MHZSTRE BIT(2) -#define AB8500_SYSULPCLKCONF_TVOUTCLKDELN BIT(3) -#define AB8500_SYSULPCLKCONF_TVOUTCLKINV BIT(4) -#define AB8500_SYSULPCLKCONF_ULPCLKSTRE BIT(5) -#define AB8500_SYSULPCLKCONF_CLK27MHZBUFENA BIT(6) -#define AB8500_SYSULPCLKCONF_CLK27MHZPDENA BIT(7) - -#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK 0x03 -#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT 0 -#define AB8500_SYSULPCLKCTRL1_ULPCLKREQ BIT(2) -#define AB8500_SYSULPCLKCTRL1_4500SYSCLKREQ BIT(3) -#define AB8500_SYSULPCLKCTRL1_AUDIOCLKENA BIT(4) -#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ BIT(5) -#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ BIT(6) -#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ BIT(7) - -#define AB8500_SYSCLKCTRL_TVOUTPLLENA BIT(0) -#define AB8500_SYSCLKCTRL_TVOUTCLKENA BIT(1) -#define AB8500_SYSCLKCTRL_USBCLKENA BIT(2) - -#define AB8500_SYSCLKREQ1VALID_SYSCLKREQ1VALID BIT(0) -#define AB8500_SYSCLKREQ1VALID_ULPCLKREQ1VALID BIT(1) -#define AB8500_SYSCLKREQ1VALID_USBSYSCLKREQ1VALID BIT(2) - -#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_MASK 0x03 -#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_SHIFT 0 -#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_MASK 0x0C -#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_SHIFT 2 -#define AB8500_SYSTEMCTRLSUP_INTDB8500NOD BIT(4) - -#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF4 BIT(4) - -#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF4 BIT(4) - -#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF4 BIT(4) - -#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF4 BIT(4) - -#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF4 BIT(4) - -#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF4 BIT(4) - -#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF4 BIT(4) - -#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF2 BIT(2) -#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF3 BIT(3) -#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF4 BIT(4) - -#define AB8500_DITHERCLKCTRL_VARMDITHERENA BIT(0) -#define AB8500_DITHERCLKCTRL_VSMPS3DITHERENA BIT(1) -#define AB8500_DITHERCLKCTRL_VSMPS1DITHERENA BIT(2) -#define AB8500_DITHERCLKCTRL_VSMPS2DITHERENA BIT(3) -#define AB8500_DITHERCLKCTRL_VMODDITHERENA BIT(4) -#define AB8500_DITHERCLKCTRL_VAPEDITHERENA BIT(5) -#define AB8500_DITHERCLKCTRL_DITHERDEL_MASK 0xC0 -#define AB8500_DITHERCLKCTRL_DITHERDEL_SHIFT 6 - -#define AB8500_SWATCTRL_UPDATERF BIT(0) -#define AB8500_SWATCTRL_SWATENABLE BIT(1) -#define AB8500_SWATCTRL_RFOFFTIMER_MASK 0x1C -#define AB8500_SWATCTRL_RFOFFTIMER_SHIFT 2 -#define AB8500_SWATCTRL_SWATBIT5 BIT(6) - -#define AB8500_HIQCLKCTRL_SYSCLKREQ1HIQENAVALID BIT(0) -#define AB8500_HIQCLKCTRL_SYSCLKREQ2HIQENAVALID BIT(1) -#define AB8500_HIQCLKCTRL_SYSCLKREQ3HIQENAVALID BIT(2) -#define AB8500_HIQCLKCTRL_SYSCLKREQ4HIQENAVALID BIT(3) -#define AB8500_HIQCLKCTRL_SYSCLKREQ5HIQENAVALID BIT(4) -#define AB8500_HIQCLKCTRL_SYSCLKREQ6HIQENAVALID BIT(5) -#define AB8500_HIQCLKCTRL_SYSCLKREQ7HIQENAVALID BIT(6) -#define AB8500_HIQCLKCTRL_SYSCLKREQ8HIQENAVALID BIT(7) - -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ1VALID BIT(0) -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ2VALID BIT(1) -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ3VALID BIT(2) -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ4VALID BIT(3) -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ5VALID BIT(4) -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ6VALID BIT(5) -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ7VALID BIT(6) -#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ8VALID BIT(7) - -#endif /* __AB8500_SYSCTRL_H */ diff --git a/include/linux/mfd/abx500/ab5500.h b/include/linux/mfd/abx500/ab5500.h new file mode 100644 index 00000000000..a720051ae93 --- /dev/null +++ b/include/linux/mfd/abx500/ab5500.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) ST-Ericsson 2011 + * + * License Terms: GNU General Public License v2 + */ +#ifndef MFD_AB5500_H +#define MFD_AB5500_H + +#include + +enum ab5500_devid { + AB5500_DEVID_ADC, + AB5500_DEVID_LEDS, + AB5500_DEVID_POWER, + AB5500_DEVID_REGULATORS, + AB5500_DEVID_SIM, + AB5500_DEVID_RTC, + AB5500_DEVID_CHARGER, + AB5500_DEVID_FUELGAUGE, + AB5500_DEVID_VIBRATOR, + AB5500_DEVID_CODEC, + AB5500_DEVID_USB, + AB5500_DEVID_OTP, + AB5500_DEVID_VIDEO, + AB5500_DEVID_DBIECI, + AB5500_DEVID_ONSWA, + AB5500_NUM_DEVICES, +}; + +enum ab5500_banks { + AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP = 0, + AB5500_BANK_VDDDIG_IO_I2C_CLK_TST = 1, + AB5500_BANK_VDENC = 2, + AB5500_BANK_SIM_USBSIM = 3, + AB5500_BANK_LED = 4, + AB5500_BANK_ADC = 5, + AB5500_BANK_RTC = 6, + AB5500_BANK_STARTUP = 7, + AB5500_BANK_DBI_ECI = 8, + AB5500_BANK_CHG = 9, + AB5500_BANK_FG_BATTCOM_ACC = 10, + AB5500_BANK_USB = 11, + AB5500_BANK_IT = 12, + AB5500_BANK_VIBRA = 13, + AB5500_BANK_AUDIO_HEADSETUSB = 14, + AB5500_NUM_BANKS = 15, +}; + +enum ab5500_banks_addr { + AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP = 0x4A, + AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST = 0x4B, + AB5500_ADDR_VDENC = 0x06, + AB5500_ADDR_SIM_USBSIM = 0x04, + AB5500_ADDR_LED = 0x10, + AB5500_ADDR_ADC = 0x0A, + AB5500_ADDR_RTC = 0x0F, + AB5500_ADDR_STARTUP = 0x03, + AB5500_ADDR_DBI_ECI = 0x07, + AB5500_ADDR_CHG = 0x0B, + AB5500_ADDR_FG_BATTCOM_ACC = 0x0C, + AB5500_ADDR_USB = 0x05, + AB5500_ADDR_IT = 0x0E, + AB5500_ADDR_VIBRA = 0x02, + AB5500_ADDR_AUDIO_HEADSETUSB = 0x0D, +}; + +/* + * Interrupt register offsets + * Bank : 0x0E + */ +#define AB5500_IT_SOURCE0_REG 0x20 +#define AB5500_IT_SOURCE1_REG 0x21 +#define AB5500_IT_SOURCE2_REG 0x22 +#define AB5500_IT_SOURCE3_REG 0x23 +#define AB5500_IT_SOURCE4_REG 0x24 +#define AB5500_IT_SOURCE5_REG 0x25 +#define AB5500_IT_SOURCE6_REG 0x26 +#define AB5500_IT_SOURCE7_REG 0x27 +#define AB5500_IT_SOURCE8_REG 0x28 +#define AB5500_IT_SOURCE9_REG 0x29 +#define AB5500_IT_SOURCE10_REG 0x2A +#define AB5500_IT_SOURCE11_REG 0x2B +#define AB5500_IT_SOURCE12_REG 0x2C +#define AB5500_IT_SOURCE13_REG 0x2D +#define AB5500_IT_SOURCE14_REG 0x2E +#define AB5500_IT_SOURCE15_REG 0x2F +#define AB5500_IT_SOURCE16_REG 0x30 +#define AB5500_IT_SOURCE17_REG 0x31 +#define AB5500_IT_SOURCE18_REG 0x32 +#define AB5500_IT_SOURCE19_REG 0x33 +#define AB5500_IT_SOURCE20_REG 0x34 +#define AB5500_IT_SOURCE21_REG 0x35 +#define AB5500_IT_SOURCE22_REG 0x36 +#define AB5500_IT_SOURCE23_REG 0x37 + +#define AB5500_NUM_IRQ_REGS 23 + +/** + * struct ab5500 + * @access_mutex: lock out concurrent accesses to the AB registers + * @dev: a pointer to the device struct for this chip driver + * @ab5500_irq: the analog baseband irq + * @irq_base: the platform configuration irq base for subdevices + * @chip_name: name of this chip variant + * @chip_id: 8 bit chip ID for this chip variant + * @irq_lock: a lock to protect the mask + * @abb_events: a local bit mask of the prcmu wakeup events + * @event_mask: a local copy of the mask event registers + * @last_event_mask: a copy of the last event_mask written to hardware + * @startup_events: a copy of the first reading of the event registers + * @startup_events_read: whether the first events have been read + */ +struct ab5500 { + struct mutex access_mutex; + struct device *dev; + unsigned int ab5500_irq; + unsigned int irq_base; + char chip_name[32]; + u8 chip_id; + struct mutex irq_lock; + u32 abb_events; + u8 mask[AB5500_NUM_IRQ_REGS]; + u8 oldmask[AB5500_NUM_IRQ_REGS]; + u8 startup_events[AB5500_NUM_IRQ_REGS]; + bool startup_events_read; +#ifdef CONFIG_DEBUG_FS + unsigned int debug_bank; + unsigned int debug_address; +#endif +}; + +struct ab5500_platform_data { + struct {unsigned int base; unsigned int count; } irq; + void *dev_data[AB5500_NUM_DEVICES]; + struct abx500_init_settings *init_settings; + unsigned int init_settings_sz; + bool pm_power_off; +}; + +#endif /* MFD_AB5500_H */ diff --git a/include/linux/mfd/abx500/ab8500-gpadc.h b/include/linux/mfd/abx500/ab8500-gpadc.h new file mode 100644 index 00000000000..252966769d9 --- /dev/null +++ b/include/linux/mfd/abx500/ab8500-gpadc.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010 ST-Ericsson SA + * Licensed under GPLv2. + * + * Author: Arun R Murthy + * Author: Daniel Willerud + */ + +#ifndef _AB8500_GPADC_H +#define _AB8500_GPADC_H + +/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2) */ +#define BAT_CTRL 0x01 +#define BTEMP_BALL 0x02 +#define MAIN_CHARGER_V 0x03 +#define ACC_DETECT1 0x04 +#define ACC_DETECT2 0x05 +#define ADC_AUX1 0x06 +#define ADC_AUX2 0x07 +#define MAIN_BAT_V 0x08 +#define VBUS_V 0x09 +#define MAIN_CHARGER_C 0x0A +#define USB_CHARGER_C 0x0B +#define BK_BAT_V 0x0C +#define DIE_TEMP 0x0D + +struct ab8500_gpadc; + +struct ab8500_gpadc *ab8500_gpadc_get(char *name); +int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel); +int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel); +int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, + u8 channel, int ad_value); + +#endif /* _AB8500_GPADC_H */ diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h new file mode 100644 index 00000000000..488a8c920a2 --- /dev/null +++ b/include/linux/mfd/abx500/ab8500-gpio.h @@ -0,0 +1,21 @@ +/* + * Copyright ST-Ericsson 2010. + * + * Author: Bibek Basu + * Licensed under GPLv2. + */ + +#ifndef _AB8500_GPIO_H +#define _AB8500_GPIO_H + +/* + * Platform data to register a block: only the initial gpio/irq number. + */ + +struct ab8500_gpio_platform_data { + int gpio_base; + u32 irq_base; + u8 config_reg[7]; +}; + +#endif /* _AB8500_GPIO_H */ diff --git a/include/linux/mfd/abx500/ab8500-sysctrl.h b/include/linux/mfd/abx500/ab8500-sysctrl.h new file mode 100644 index 00000000000..10da0291f8f --- /dev/null +++ b/include/linux/mfd/abx500/ab8500-sysctrl.h @@ -0,0 +1,254 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Mattias Nilsson for ST Ericsson. + * License terms: GNU General Public License (GPL) version 2 + */ +#ifndef __AB8500_SYSCTRL_H +#define __AB8500_SYSCTRL_H + +#include + +#ifdef CONFIG_AB8500_CORE + +int ab8500_sysctrl_read(u16 reg, u8 *value); +int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value); + +#else + +static inline int ab8500_sysctrl_read(u16 reg, u8 *value) +{ + return 0; +} + +static inline int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) +{ + return 0; +} + +#endif /* CONFIG_AB8500_CORE */ + +static inline int ab8500_sysctrl_set(u16 reg, u8 bits) +{ + return ab8500_sysctrl_write(reg, bits, bits); +} + +static inline int ab8500_sysctrl_clear(u16 reg, u8 bits) +{ + return ab8500_sysctrl_write(reg, bits, 0); +} + +/* Registers */ +#define AB8500_TURNONSTATUS 0x100 +#define AB8500_RESETSTATUS 0x101 +#define AB8500_PONKEY1PRESSSTATUS 0x102 +#define AB8500_SYSCLKREQSTATUS 0x142 +#define AB8500_STW4500CTRL1 0x180 +#define AB8500_STW4500CTRL2 0x181 +#define AB8500_STW4500CTRL3 0x200 +#define AB8500_MAINWDOGCTRL 0x201 +#define AB8500_MAINWDOGTIMER 0x202 +#define AB8500_LOWBAT 0x203 +#define AB8500_BATTOK 0x204 +#define AB8500_SYSCLKTIMER 0x205 +#define AB8500_SMPSCLKCTRL 0x206 +#define AB8500_SMPSCLKSEL1 0x207 +#define AB8500_SMPSCLKSEL2 0x208 +#define AB8500_SMPSCLKSEL3 0x209 +#define AB8500_SYSULPCLKCONF 0x20A +#define AB8500_SYSULPCLKCTRL1 0x20B +#define AB8500_SYSCLKCTRL 0x20C +#define AB8500_SYSCLKREQ1VALID 0x20D +#define AB8500_SYSTEMCTRLSUP 0x20F +#define AB8500_SYSCLKREQ1RFCLKBUF 0x210 +#define AB8500_SYSCLKREQ2RFCLKBUF 0x211 +#define AB8500_SYSCLKREQ3RFCLKBUF 0x212 +#define AB8500_SYSCLKREQ4RFCLKBUF 0x213 +#define AB8500_SYSCLKREQ5RFCLKBUF 0x214 +#define AB8500_SYSCLKREQ6RFCLKBUF 0x215 +#define AB8500_SYSCLKREQ7RFCLKBUF 0x216 +#define AB8500_SYSCLKREQ8RFCLKBUF 0x217 +#define AB8500_DITHERCLKCTRL 0x220 +#define AB8500_SWATCTRL 0x230 +#define AB8500_HIQCLKCTRL 0x232 +#define AB8500_VSIMSYSCLKCTRL 0x233 + +/* Bits */ +#define AB8500_TURNONSTATUS_PORNVBAT BIT(0) +#define AB8500_TURNONSTATUS_PONKEY1DBF BIT(1) +#define AB8500_TURNONSTATUS_PONKEY2DBF BIT(2) +#define AB8500_TURNONSTATUS_RTCALARM BIT(3) +#define AB8500_TURNONSTATUS_MAINCHDET BIT(4) +#define AB8500_TURNONSTATUS_VBUSDET BIT(5) +#define AB8500_TURNONSTATUS_USBIDDETECT BIT(6) + +#define AB8500_RESETSTATUS_RESETN4500NSTATUS BIT(0) +#define AB8500_RESETSTATUS_SWRESETN4500NSTATUS BIT(2) + +#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_MASK 0x7F +#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_SHIFT 0 + +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ1STATUS BIT(0) +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ2STATUS BIT(1) +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ3STATUS BIT(2) +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ4STATUS BIT(3) +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ5STATUS BIT(4) +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ6STATUS BIT(5) +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ7STATUS BIT(6) +#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ8STATUS BIT(7) + +#define AB8500_STW4500CTRL1_SWOFF BIT(0) +#define AB8500_STW4500CTRL1_SWRESET4500N BIT(1) +#define AB8500_STW4500CTRL1_THDB8500SWOFF BIT(2) + +#define AB8500_STW4500CTRL2_RESETNVAUX1VALID BIT(0) +#define AB8500_STW4500CTRL2_RESETNVAUX2VALID BIT(1) +#define AB8500_STW4500CTRL2_RESETNVAUX3VALID BIT(2) +#define AB8500_STW4500CTRL2_RESETNVMODVALID BIT(3) +#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY1VALID BIT(4) +#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY2VALID BIT(5) +#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY3VALID BIT(6) +#define AB8500_STW4500CTRL2_RESETNVSMPS1VALID BIT(7) + +#define AB8500_STW4500CTRL3_CLK32KOUT2DIS BIT(0) +#define AB8500_STW4500CTRL3_RESETAUDN BIT(1) +#define AB8500_STW4500CTRL3_RESETDENCN BIT(2) +#define AB8500_STW4500CTRL3_THSDENA BIT(3) + +#define AB8500_MAINWDOGCTRL_MAINWDOGENA BIT(0) +#define AB8500_MAINWDOGCTRL_MAINWDOGKICK BIT(1) +#define AB8500_MAINWDOGCTRL_WDEXPTURNONVALID BIT(4) + +#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_MASK 0x7F +#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_SHIFT 0 + +#define AB8500_LOWBAT_LOWBATENA BIT(0) +#define AB8500_LOWBAT_LOWBAT_MASK 0x7E +#define AB8500_LOWBAT_LOWBAT_SHIFT 1 + +#define AB8500_BATTOK_BATTOKSEL0THF_MASK 0x0F +#define AB8500_BATTOK_BATTOKSEL0THF_SHIFT 0 +#define AB8500_BATTOK_BATTOKSEL1THF_MASK 0xF0 +#define AB8500_BATTOK_BATTOKSEL1THF_SHIFT 4 + +#define AB8500_SYSCLKTIMER_SYSCLKTIMER_MASK 0x0F +#define AB8500_SYSCLKTIMER_SYSCLKTIMER_SHIFT 0 +#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_MASK 0xF0 +#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_SHIFT 4 + +#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_MASK 0x03 +#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_SHIFT 0 +#define AB8500_SMPSCLKCTRL_3M2CLKINTENA BIT(2) + +#define AB8500_SMPSCLKSEL1_VARMCLKSEL_MASK 0x07 +#define AB8500_SMPSCLKSEL1_VARMCLKSEL_SHIFT 0 +#define AB8500_SMPSCLKSEL1_VAPECLKSEL_MASK 0x38 +#define AB8500_SMPSCLKSEL1_VAPECLKSEL_SHIFT 3 + +#define AB8500_SMPSCLKSEL2_VMODCLKSEL_MASK 0x07 +#define AB8500_SMPSCLKSEL2_VMODCLKSEL_SHIFT 0 +#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_MASK 0x38 +#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_SHIFT 3 + +#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_MASK 0x07 +#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_SHIFT 0 +#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_MASK 0x38 +#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_SHIFT 3 + +#define AB8500_SYSULPCLKCONF_ULPCLKCONF_MASK 0x03 +#define AB8500_SYSULPCLKCONF_ULPCLKCONF_SHIFT 0 +#define AB8500_SYSULPCLKCONF_CLK27MHZSTRE BIT(2) +#define AB8500_SYSULPCLKCONF_TVOUTCLKDELN BIT(3) +#define AB8500_SYSULPCLKCONF_TVOUTCLKINV BIT(4) +#define AB8500_SYSULPCLKCONF_ULPCLKSTRE BIT(5) +#define AB8500_SYSULPCLKCONF_CLK27MHZBUFENA BIT(6) +#define AB8500_SYSULPCLKCONF_CLK27MHZPDENA BIT(7) + +#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK 0x03 +#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT 0 +#define AB8500_SYSULPCLKCTRL1_ULPCLKREQ BIT(2) +#define AB8500_SYSULPCLKCTRL1_4500SYSCLKREQ BIT(3) +#define AB8500_SYSULPCLKCTRL1_AUDIOCLKENA BIT(4) +#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ BIT(5) +#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ BIT(6) +#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ BIT(7) + +#define AB8500_SYSCLKCTRL_TVOUTPLLENA BIT(0) +#define AB8500_SYSCLKCTRL_TVOUTCLKENA BIT(1) +#define AB8500_SYSCLKCTRL_USBCLKENA BIT(2) + +#define AB8500_SYSCLKREQ1VALID_SYSCLKREQ1VALID BIT(0) +#define AB8500_SYSCLKREQ1VALID_ULPCLKREQ1VALID BIT(1) +#define AB8500_SYSCLKREQ1VALID_USBSYSCLKREQ1VALID BIT(2) + +#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_MASK 0x03 +#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_SHIFT 0 +#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_MASK 0x0C +#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_SHIFT 2 +#define AB8500_SYSTEMCTRLSUP_INTDB8500NOD BIT(4) + +#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF4 BIT(4) + +#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF4 BIT(4) + +#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF4 BIT(4) + +#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF4 BIT(4) + +#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF4 BIT(4) + +#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF4 BIT(4) + +#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF4 BIT(4) + +#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF2 BIT(2) +#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF3 BIT(3) +#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF4 BIT(4) + +#define AB8500_DITHERCLKCTRL_VARMDITHERENA BIT(0) +#define AB8500_DITHERCLKCTRL_VSMPS3DITHERENA BIT(1) +#define AB8500_DITHERCLKCTRL_VSMPS1DITHERENA BIT(2) +#define AB8500_DITHERCLKCTRL_VSMPS2DITHERENA BIT(3) +#define AB8500_DITHERCLKCTRL_VMODDITHERENA BIT(4) +#define AB8500_DITHERCLKCTRL_VAPEDITHERENA BIT(5) +#define AB8500_DITHERCLKCTRL_DITHERDEL_MASK 0xC0 +#define AB8500_DITHERCLKCTRL_DITHERDEL_SHIFT 6 + +#define AB8500_SWATCTRL_UPDATERF BIT(0) +#define AB8500_SWATCTRL_SWATENABLE BIT(1) +#define AB8500_SWATCTRL_RFOFFTIMER_MASK 0x1C +#define AB8500_SWATCTRL_RFOFFTIMER_SHIFT 2 +#define AB8500_SWATCTRL_SWATBIT5 BIT(6) + +#define AB8500_HIQCLKCTRL_SYSCLKREQ1HIQENAVALID BIT(0) +#define AB8500_HIQCLKCTRL_SYSCLKREQ2HIQENAVALID BIT(1) +#define AB8500_HIQCLKCTRL_SYSCLKREQ3HIQENAVALID BIT(2) +#define AB8500_HIQCLKCTRL_SYSCLKREQ4HIQENAVALID BIT(3) +#define AB8500_HIQCLKCTRL_SYSCLKREQ5HIQENAVALID BIT(4) +#define AB8500_HIQCLKCTRL_SYSCLKREQ6HIQENAVALID BIT(5) +#define AB8500_HIQCLKCTRL_SYSCLKREQ7HIQENAVALID BIT(6) +#define AB8500_HIQCLKCTRL_SYSCLKREQ8HIQENAVALID BIT(7) + +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ1VALID BIT(0) +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ2VALID BIT(1) +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ3VALID BIT(2) +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ4VALID BIT(3) +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ5VALID BIT(4) +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ6VALID BIT(5) +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ7VALID BIT(6) +#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ8VALID BIT(7) + +#endif /* __AB8500_SYSCTRL_H */ diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h new file mode 100644 index 00000000000..838c6b487cc --- /dev/null +++ b/include/linux/mfd/abx500/ab8500.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Srinidhi Kasagar + */ +#ifndef MFD_AB8500_H +#define MFD_AB8500_H + +#include + +/* + * AB8500 bank addresses + */ +#define AB8500_SYS_CTRL1_BLOCK 0x1 +#define AB8500_SYS_CTRL2_BLOCK 0x2 +#define AB8500_REGU_CTRL1 0x3 +#define AB8500_REGU_CTRL2 0x4 +#define AB8500_USB 0x5 +#define AB8500_TVOUT 0x6 +#define AB8500_DBI 0x7 +#define AB8500_ECI_AV_ACC 0x8 +#define AB8500_RESERVED 0x9 +#define AB8500_GPADC 0xA +#define AB8500_CHARGER 0xB +#define AB8500_GAS_GAUGE 0xC +#define AB8500_AUDIO 0xD +#define AB8500_INTERRUPT 0xE +#define AB8500_RTC 0xF +#define AB8500_MISC 0x10 +#define AB8500_DEVELOPMENT 0x11 +#define AB8500_DEBUG 0x12 +#define AB8500_PROD_TEST 0x13 +#define AB8500_OTP_EMUL 0x15 + +/* + * Interrupts + */ + +#define AB8500_INT_MAIN_EXT_CH_NOT_OK 0 +#define AB8500_INT_UN_PLUG_TV_DET 1 +#define AB8500_INT_PLUG_TV_DET 2 +#define AB8500_INT_TEMP_WARM 3 +#define AB8500_INT_PON_KEY2DB_F 4 +#define AB8500_INT_PON_KEY2DB_R 5 +#define AB8500_INT_PON_KEY1DB_F 6 +#define AB8500_INT_PON_KEY1DB_R 7 +#define AB8500_INT_BATT_OVV 8 +#define AB8500_INT_MAIN_CH_UNPLUG_DET 10 +#define AB8500_INT_MAIN_CH_PLUG_DET 11 +#define AB8500_INT_USB_ID_DET_F 12 +#define AB8500_INT_USB_ID_DET_R 13 +#define AB8500_INT_VBUS_DET_F 14 +#define AB8500_INT_VBUS_DET_R 15 +#define AB8500_INT_VBUS_CH_DROP_END 16 +#define AB8500_INT_RTC_60S 17 +#define AB8500_INT_RTC_ALARM 18 +#define AB8500_INT_BAT_CTRL_INDB 20 +#define AB8500_INT_CH_WD_EXP 21 +#define AB8500_INT_VBUS_OVV 22 +#define AB8500_INT_MAIN_CH_DROP_END 23 +#define AB8500_INT_CCN_CONV_ACC 24 +#define AB8500_INT_INT_AUD 25 +#define AB8500_INT_CCEOC 26 +#define AB8500_INT_CC_INT_CALIB 27 +#define AB8500_INT_LOW_BAT_F 28 +#define AB8500_INT_LOW_BAT_R 29 +#define AB8500_INT_BUP_CHG_NOT_OK 30 +#define AB8500_INT_BUP_CHG_OK 31 +#define AB8500_INT_GP_HW_ADC_CONV_END 32 +#define AB8500_INT_ACC_DETECT_1DB_F 33 +#define AB8500_INT_ACC_DETECT_1DB_R 34 +#define AB8500_INT_ACC_DETECT_22DB_F 35 +#define AB8500_INT_ACC_DETECT_22DB_R 36 +#define AB8500_INT_ACC_DETECT_21DB_F 37 +#define AB8500_INT_ACC_DETECT_21DB_R 38 +#define AB8500_INT_GP_SW_ADC_CONV_END 39 +#define AB8500_INT_GPIO6R 40 +#define AB8500_INT_GPIO7R 41 +#define AB8500_INT_GPIO8R 42 +#define AB8500_INT_GPIO9R 43 +#define AB8500_INT_GPIO10R 44 +#define AB8500_INT_GPIO11R 45 +#define AB8500_INT_GPIO12R 46 +#define AB8500_INT_GPIO13R 47 +#define AB8500_INT_GPIO24R 48 +#define AB8500_INT_GPIO25R 49 +#define AB8500_INT_GPIO36R 50 +#define AB8500_INT_GPIO37R 51 +#define AB8500_INT_GPIO38R 52 +#define AB8500_INT_GPIO39R 53 +#define AB8500_INT_GPIO40R 54 +#define AB8500_INT_GPIO41R 55 +#define AB8500_INT_GPIO6F 56 +#define AB8500_INT_GPIO7F 57 +#define AB8500_INT_GPIO8F 58 +#define AB8500_INT_GPIO9F 59 +#define AB8500_INT_GPIO10F 60 +#define AB8500_INT_GPIO11F 61 +#define AB8500_INT_GPIO12F 62 +#define AB8500_INT_GPIO13F 63 +#define AB8500_INT_GPIO24F 64 +#define AB8500_INT_GPIO25F 65 +#define AB8500_INT_GPIO36F 66 +#define AB8500_INT_GPIO37F 67 +#define AB8500_INT_GPIO38F 68 +#define AB8500_INT_GPIO39F 69 +#define AB8500_INT_GPIO40F 70 +#define AB8500_INT_GPIO41F 71 +#define AB8500_INT_ADP_SOURCE_ERROR 72 +#define AB8500_INT_ADP_SINK_ERROR 73 +#define AB8500_INT_ADP_PROBE_PLUG 74 +#define AB8500_INT_ADP_PROBE_UNPLUG 75 +#define AB8500_INT_ADP_SENSE_OFF 76 +#define AB8500_INT_USB_PHY_POWER_ERR 78 +#define AB8500_INT_USB_LINK_STATUS 79 +#define AB8500_INT_BTEMP_LOW 80 +#define AB8500_INT_BTEMP_LOW_MEDIUM 81 +#define AB8500_INT_BTEMP_MEDIUM_HIGH 82 +#define AB8500_INT_BTEMP_HIGH 83 +#define AB8500_INT_USB_CHARGER_NOT_OK 89 +#define AB8500_INT_ID_WAKEUP_R 90 +#define AB8500_INT_ID_DET_R1R 92 +#define AB8500_INT_ID_DET_R2R 93 +#define AB8500_INT_ID_DET_R3R 94 +#define AB8500_INT_ID_DET_R4R 95 +#define AB8500_INT_ID_WAKEUP_F 96 +#define AB8500_INT_ID_DET_R1F 98 +#define AB8500_INT_ID_DET_R2F 99 +#define AB8500_INT_ID_DET_R3F 100 +#define AB8500_INT_ID_DET_R4F 101 +#define AB8500_INT_USB_CHG_DET_DONE 102 +#define AB8500_INT_USB_CH_TH_PROT_F 104 +#define AB8500_INT_USB_CH_TH_PROT_R 105 +#define AB8500_INT_MAIN_CH_TH_PROT_F 106 +#define AB8500_INT_MAIN_CH_TH_PROT_R 107 +#define AB8500_INT_USB_CHARGER_NOT_OKF 111 + +#define AB8500_NR_IRQS 112 +#define AB8500_NUM_IRQ_REGS 14 + +/** + * struct ab8500 - ab8500 internal structure + * @dev: parent device + * @lock: read/write operations lock + * @irq_lock: genirq bus lock + * @irq: irq line + * @chip_id: chip revision id + * @write: register write + * @read: register read + * @rx_buf: rx buf for SPI + * @tx_buf: tx buf for SPI + * @mask: cache of IRQ regs for bus lock + * @oldmask: cache of previous IRQ regs for bus lock + */ +struct ab8500 { + struct device *dev; + struct mutex lock; + struct mutex irq_lock; + + int irq_base; + int irq; + u8 chip_id; + + int (*write) (struct ab8500 *a8500, u16 addr, u8 data); + int (*read) (struct ab8500 *a8500, u16 addr); + + unsigned long tx_buf[4]; + unsigned long rx_buf[4]; + + u8 mask[AB8500_NUM_IRQ_REGS]; + u8 oldmask[AB8500_NUM_IRQ_REGS]; +}; + +struct regulator_reg_init; +struct regulator_init_data; +struct ab8500_gpio_platform_data; + +/** + * struct ab8500_platform_data - AB8500 platform data + * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used + * @init: board-specific initialization after detection of ab8500 + * @num_regulator_reg_init: number of regulator init registers + * @regulator_reg_init: regulator init registers + * @num_regulator: number of regulators + * @regulator: machine-specific constraints for regulators + */ +struct ab8500_platform_data { + int irq_base; + void (*init) (struct ab8500 *); + int num_regulator_reg_init; + struct ab8500_regulator_reg_init *regulator_reg_init; + int num_regulator; + struct regulator_init_data *regulator; + struct ab8500_gpio_platform_data *gpio; +}; + +extern int __devinit ab8500_init(struct ab8500 *ab8500); +extern int __devexit ab8500_exit(struct ab8500 *ab8500); + +#endif /* MFD_AB8500_H */ -- cgit v1.2.3-70-g09d2 From f6dd2db940a1a0c6b9f7112109115c8243ba752b Mon Sep 17 00:00:00 2001 From: Donggeun Kim Date: Wed, 14 Dec 2011 18:23:55 +0900 Subject: mfd: Add platform data and devices for MAX8997 LED control MAX8997 device does not support LED control function of it. To enable MAX8997-LED driver, platform data and devices for LED are updated. Signed-off-by: Donggeun Kim Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Signed-off-by: Samuel Ortiz --- drivers/mfd/max8997.c | 3 ++- include/linux/mfd/max8997.h | 25 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'include/linux/mfd') diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 5be53ae9b61..cb83a7ab53e 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -43,7 +43,8 @@ static struct mfd_cell max8997_devs[] = { { .name = "max8997-battery", }, { .name = "max8997-haptic", }, { .name = "max8997-muic", }, - { .name = "max8997-flash", }, + { .name = "max8997-led", .id = 1 }, + { .name = "max8997-led", .id = 2 }, }; int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 49d2a0bfd7f..fff590521e5 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -131,6 +131,28 @@ struct max8997_muic_platform_data { int num_init_data; }; +enum max8997_led_mode { + MAX8997_NONE, + MAX8997_FLASH_MODE, + MAX8997_MOVIE_MODE, + MAX8997_FLASH_PIN_CONTROL_MODE, + MAX8997_MOVIE_PIN_CONTROL_MODE, +}; + +/** + * struct max8997_led_platform_data + * The number of LED devices for MAX8997 is two + * @mode: LED mode for each LED device + * @brightness: initial brightness for each LED device + * range: + * [0 - 31]: MAX8997_FLASH_MODE and MAX8997_FLASH_PIN_CONTROL_MODE + * [0 - 15]: MAX8997_MOVIE_MODE and MAX8997_MOVIE_PIN_CONTROL_MODE + */ +struct max8997_led_platform_data { + enum max8997_led_mode mode[2]; + u8 brightness[2]; +}; + struct max8997_platform_data { /* IRQ */ int irq_base; @@ -172,7 +194,8 @@ struct max8997_platform_data { /* HAPTIC: Not implemented */ /* RTC: Not implemented */ - /* Flash: Not implemented */ + /* ---- LED ---- */ + struct max8997_led_platform_data *led_pdata; }; #endif /* __LINUX_MFD_MAX8998_H */ -- cgit v1.2.3-70-g09d2 From 1a6e4b7415339e3b11a87cff0d701b8a2e55f062 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 17 Nov 2011 11:02:20 +0530 Subject: mfd: Separate out STMPE controller and interface specific code Few STMPE controller can have register interface over SPI or I2C. Current implementation only supports I2C and all code is present in a single file stmpe.c. It would be better to separate out I2C interface specific code from controller specific code. Later SPI specific code can be added in a separate file. This patch separates out I2C and controller specific code into separate files, making stmpe.c independent of I2C. Signed-off-by: Viresh Kumar Acked-by: Linus Walleij Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 11 ++++ drivers/mfd/Makefile | 1 + drivers/mfd/stmpe-i2c.c | 107 +++++++++++++++++++++++++++++++++++++ drivers/mfd/stmpe.c | 133 +++++++++++++++------------------------------- drivers/mfd/stmpe.h | 33 ++++++++++++ include/linux/mfd/stmpe.h | 7 ++- 6 files changed, 200 insertions(+), 92 deletions(-) create mode 100644 drivers/mfd/stmpe-i2c.c (limited to 'include/linux/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 08a3e087bce..7bc55819ab4 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -279,6 +279,17 @@ config MFD_STMPE Keypad: stmpe-keypad Touchscreen: stmpe-ts +menu "STMPE Interface Drivers" +depends on MFD_STMPE + +config STMPE_I2C + bool "STMPE I2C Inteface" + depends on I2C + default y + help + This is used to enable I2C interface of STMPE +endmenu + config MFD_TC3589X bool "Support Toshiba TC35892 and variants" depends on I2C=y && GENERIC_HARDIRQS diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index b2292eb7524..5eb90a70c1a 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o obj-$(CONFIG_MFD_STMPE) += stmpe.o +obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o obj-$(CONFIG_MFD_TC3589X) += tc3589x.o obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c new file mode 100644 index 00000000000..0a4365902e3 --- /dev/null +++ b/drivers/mfd/stmpe-i2c.c @@ -0,0 +1,107 @@ +/* + * ST Microelectronics MFD: stmpe's i2c client specific driver + * + * Copyright (C) ST-Ericsson SA 2010 + * Copyright (C) ST Microelectronics SA 2011 + * + * License Terms: GNU General Public License, version 2 + * Author: Rabin Vincent for ST-Ericsson + * Author: Viresh Kumar for ST Microelectronics + */ + +#include +#include +#include +#include +#include +#include "stmpe.h" + +static int i2c_reg_read(struct stmpe *stmpe, u8 reg) +{ + struct i2c_client *i2c = stmpe->client; + + return i2c_smbus_read_byte_data(i2c, reg); +} + +static int i2c_reg_write(struct stmpe *stmpe, u8 reg, u8 val) +{ + struct i2c_client *i2c = stmpe->client; + + return i2c_smbus_write_byte_data(i2c, reg, val); +} + +static int i2c_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) +{ + struct i2c_client *i2c = stmpe->client; + + return i2c_smbus_read_i2c_block_data(i2c, reg, length, values); +} + +static int i2c_block_write(struct stmpe *stmpe, u8 reg, u8 length, + const u8 *values) +{ + struct i2c_client *i2c = stmpe->client; + + return i2c_smbus_write_i2c_block_data(i2c, reg, length, values); +} + +static struct stmpe_client_info i2c_ci = { + .read_byte = i2c_reg_read, + .write_byte = i2c_reg_write, + .read_block = i2c_block_read, + .write_block = i2c_block_write, +}; + +static int __devinit +stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +{ + i2c_ci.data = (void *)id; + i2c_ci.irq = i2c->irq; + i2c_ci.client = i2c; + i2c_ci.dev = &i2c->dev; + + return stmpe_probe(&i2c_ci, id->driver_data); +} + +static int __devexit stmpe_i2c_remove(struct i2c_client *i2c) +{ + struct stmpe *stmpe = dev_get_drvdata(&i2c->dev); + + return stmpe_remove(stmpe); +} + +static const struct i2c_device_id stmpe_i2c_id[] = { + { "stmpe811", STMPE811 }, + { "stmpe1601", STMPE1601 }, + { "stmpe2401", STMPE2401 }, + { "stmpe2403", STMPE2403 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, stmpe_id); + +static struct i2c_driver stmpe_i2c_driver = { + .driver.name = "stmpe-i2c", + .driver.owner = THIS_MODULE, +#ifdef CONFIG_PM + .driver.pm = &stmpe_dev_pm_ops, +#endif + .probe = stmpe_i2c_probe, + .remove = __devexit_p(stmpe_i2c_remove), + .id_table = stmpe_i2c_id, +}; + +static int __init stmpe_init(void) +{ + return i2c_add_driver(&stmpe_i2c_driver); +} +subsys_initcall(stmpe_init); + +static void __exit stmpe_exit(void) +{ + i2c_del_driver(&stmpe_i2c_driver); +} +module_exit(stmpe_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver"); +MODULE_AUTHOR("Rabin Vincent "); diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 39efa629a19..83bacde6a7c 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -1,4 +1,6 @@ /* + * ST Microelectronics MFD: stmpe's driver + * * Copyright (C) ST-Ericsson SA 2010 * * License Terms: GNU General Public License, version 2 @@ -7,13 +9,11 @@ #include #include -#include #include #include +#include #include -#include #include -#include #include "stmpe.h" static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) @@ -30,10 +30,9 @@ static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg) { int ret; - ret = i2c_smbus_read_byte_data(stmpe->i2c, reg); + ret = stmpe->ci->read_byte(stmpe, reg); if (ret < 0) - dev_err(stmpe->dev, "failed to read reg %#x: %d\n", - reg, ret); + dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret); dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); @@ -46,10 +45,9 @@ static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); - ret = i2c_smbus_write_byte_data(stmpe->i2c, reg, val); + ret = stmpe->ci->write_byte(stmpe, reg, val); if (ret < 0) - dev_err(stmpe->dev, "failed to write reg %#x: %d\n", - reg, ret); + dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret); return ret; } @@ -73,10 +71,9 @@ static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, { int ret; - ret = i2c_smbus_read_i2c_block_data(stmpe->i2c, reg, length, values); + ret = stmpe->ci->read_block(stmpe, reg, length, values); if (ret < 0) - dev_err(stmpe->dev, "failed to read regs %#x: %d\n", - reg, ret); + dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret); dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); stmpe_dump_bytes("stmpe rd: ", values, length); @@ -92,11 +89,9 @@ static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); stmpe_dump_bytes("stmpe wr: ", values, length); - ret = i2c_smbus_write_i2c_block_data(stmpe->i2c, reg, length, - values); + ret = stmpe->ci->write_block(stmpe, reg, length, values); if (ret < 0) - dev_err(stmpe->dev, "failed to write regs %#x: %d\n", - reg, ret); + dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret); return ret; } @@ -874,34 +869,10 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe) return ret; } -#ifdef CONFIG_PM -static int stmpe_suspend(struct device *dev) -{ - struct i2c_client *i2c = to_i2c_client(dev); - struct stmpe *stmpe = i2c_get_clientdata(i2c); - - if (device_may_wakeup(&i2c->dev)) - enable_irq_wake(stmpe->irq); - - return 0; -} - -static int stmpe_resume(struct device *dev) +/* Called from client specific probe routines */ +int stmpe_probe(struct stmpe_client_info *ci, int partnum) { - struct i2c_client *i2c = to_i2c_client(dev); - struct stmpe *stmpe = i2c_get_clientdata(i2c); - - if (device_may_wakeup(&i2c->dev)) - disable_irq_wake(stmpe->irq); - - return 0; -} -#endif - -static int __devinit stmpe_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct stmpe_platform_data *pdata = i2c->dev.platform_data; + struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev); struct stmpe *stmpe; int ret; @@ -915,18 +886,19 @@ static int __devinit stmpe_probe(struct i2c_client *i2c, mutex_init(&stmpe->irq_lock); mutex_init(&stmpe->lock); - stmpe->dev = &i2c->dev; - stmpe->i2c = i2c; - + stmpe->dev = ci->dev; + stmpe->client = ci->client; stmpe->pdata = pdata; stmpe->irq_base = pdata->irq_base; - - stmpe->partnum = id->driver_data; - stmpe->variant = stmpe_variant_info[stmpe->partnum]; + stmpe->ci = ci; + stmpe->partnum = partnum; + stmpe->variant = stmpe_variant_info[partnum]; stmpe->regs = stmpe->variant->regs; stmpe->num_gpios = stmpe->variant->num_gpios; + dev_set_drvdata(stmpe->dev, stmpe); - i2c_set_clientdata(i2c, stmpe); + if (ci->init) + ci->init(stmpe); if (pdata->irq_over_gpio) { ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe"); @@ -938,7 +910,7 @@ static int __devinit stmpe_probe(struct i2c_client *i2c, stmpe->irq = gpio_to_irq(pdata->irq_gpio); } else { - stmpe->irq = i2c->irq; + stmpe->irq = ci->irq; } ret = stmpe_chip_init(stmpe); @@ -950,8 +922,7 @@ static int __devinit stmpe_probe(struct i2c_client *i2c, goto free_gpio; ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq, - pdata->irq_trigger | IRQF_ONESHOT, - "stmpe", stmpe); + pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe); if (ret) { dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret); goto out_removeirq; @@ -978,10 +949,8 @@ out_free: return ret; } -static int __devexit stmpe_remove(struct i2c_client *client) +int stmpe_remove(struct stmpe *stmpe) { - struct stmpe *stmpe = i2c_get_clientdata(client); - mfd_remove_devices(stmpe->dev); free_irq(stmpe->irq, stmpe); @@ -995,45 +964,29 @@ static int __devexit stmpe_remove(struct i2c_client *client) return 0; } -static const struct i2c_device_id stmpe_id[] = { - { "stmpe811", STMPE811 }, - { "stmpe1601", STMPE1601 }, - { "stmpe2401", STMPE2401 }, - { "stmpe2403", STMPE2403 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, stmpe_id); - #ifdef CONFIG_PM -static const struct dev_pm_ops stmpe_dev_pm_ops = { - .suspend = stmpe_suspend, - .resume = stmpe_resume, -}; -#endif +static int stmpe_suspend(struct device *dev) +{ + struct stmpe *stmpe = dev_get_drvdata(dev); -static struct i2c_driver stmpe_driver = { - .driver.name = "stmpe", - .driver.owner = THIS_MODULE, -#ifdef CONFIG_PM - .driver.pm = &stmpe_dev_pm_ops, -#endif - .probe = stmpe_probe, - .remove = __devexit_p(stmpe_remove), - .id_table = stmpe_id, -}; + if (device_may_wakeup(dev)) + enable_irq_wake(stmpe->irq); -static int __init stmpe_init(void) -{ - return i2c_add_driver(&stmpe_driver); + return 0; } -subsys_initcall(stmpe_init); -static void __exit stmpe_exit(void) +static int stmpe_resume(struct device *dev) { - i2c_del_driver(&stmpe_driver); + struct stmpe *stmpe = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(stmpe->irq); + + return 0; } -module_exit(stmpe_exit); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("STMPE MFD core driver"); -MODULE_AUTHOR("Rabin Vincent "); +const struct dev_pm_ops stmpe_dev_pm_ops = { + .suspend = stmpe_suspend, + .resume = stmpe_resume, +}; +#endif diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h index e4ee3895658..18d89a68ce4 100644 --- a/drivers/mfd/stmpe.h +++ b/drivers/mfd/stmpe.h @@ -8,6 +8,14 @@ #ifndef __STMPE_H #define __STMPE_H +#include +#include +#include +#include +#include + +extern const struct dev_pm_ops stmpe_dev_pm_ops; + #ifdef STMPE_DUMP_BYTES static inline void stmpe_dump_bytes(const char *str, const void *buf, size_t len) @@ -67,6 +75,31 @@ struct stmpe_variant_info { int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout); }; +/** + * struct stmpe_client_info - i2c or spi specific routines/info + * @data: client specific data + * @read_byte: read single byte + * @write_byte: write single byte + * @read_block: read block or multiple bytes + * @write_block: write block or multiple bytes + * @init: client init routine, called during probe + */ +struct stmpe_client_info { + void *data; + int irq; + void *client; + struct device *dev; + int (*read_byte)(struct stmpe *stmpe, u8 reg); + int (*write_byte)(struct stmpe *stmpe, u8 reg, u8 val); + int (*read_block)(struct stmpe *stmpe, u8 reg, u8 len, u8 *values); + int (*write_block)(struct stmpe *stmpe, u8 reg, u8 len, + const u8 *values); + void (*init)(struct stmpe *stmpe); +}; + +int stmpe_probe(struct stmpe_client_info *ci, int partnum); +int stmpe_remove(struct stmpe *stmpe); + #define STMPE_ICR_LSB_HIGH (1 << 2) #define STMPE_ICR_LSB_EDGE (1 << 1) #define STMPE_ICR_LSB_GIM (1 << 0) diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index 270d6613aad..babc6b2857d 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -50,13 +50,15 @@ enum { struct stmpe_variant_info; +struct stmpe_client_info; /** * struct stmpe - STMPE MFD structure * @lock: lock protecting I/O operations * @irq_lock: IRQ bus lock * @dev: device, mostly for dev_dbg() - * @i2c: i2c client + * @client: client - i2c or spi + * @ci: client specific information * @partnum: part number * @variant: the detected STMPE model number * @regs: list of addresses of registers which are at different addresses on @@ -72,7 +74,8 @@ struct stmpe { struct mutex lock; struct mutex irq_lock; struct device *dev; - struct i2c_client *i2c; + void *client; + struct stmpe_client_info *ci; enum stmpe_partnum partnum; struct stmpe_variant_info *variant; const u8 *regs; -- cgit v1.2.3-70-g09d2 From 1cda2394e95415f1469ab8eaffd081395e112551 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 17 Nov 2011 11:02:22 +0530 Subject: mfd: Add support for stmpe variant 610 STMPE610 is very much like STMPE811, except the number of gpio pins, which is 8 in 811 and 6 in 610. This patch adds support for variant 610. STMPE610 will share most of the code with STMPE811. Signed-off-by: Viresh Kumar Signed-off-by: Samuel Ortiz --- drivers/mfd/stmpe-i2c.c | 1 + drivers/mfd/stmpe-spi.c | 1 + drivers/mfd/stmpe.c | 20 ++++++++++++++++++-- include/linux/mfd/stmpe.h | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) (limited to 'include/linux/mfd') diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 0a4365902e3..b11d33b1c89 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -71,6 +71,7 @@ static int __devexit stmpe_i2c_remove(struct i2c_client *i2c) } static const struct i2c_device_id stmpe_i2c_id[] = { + { "stmpe610", STMPE610 }, { "stmpe811", STMPE811 }, { "stmpe1601", STMPE1601 }, { "stmpe2401", STMPE2401 }, diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index 53efce4fe29..46963a5d569 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c @@ -109,6 +109,7 @@ static int __devexit stmpe_spi_remove(struct spi_device *spi) } static const struct spi_device_id stmpe_spi_id[] = { + { "stmpe610", STMPE610 }, { "stmpe811", STMPE811 }, { "stmpe1601", STMPE1601 }, { "stmpe2401", STMPE2401 }, diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 83bacde6a7c..67ff3dc5bb4 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -321,7 +321,7 @@ static struct mfd_cell stmpe_keypad_cell = { }; /* - * Touchscreen (STMPE811) + * Touchscreen (STMPE811 or STMPE610) */ static struct resource stmpe_ts_resources[] = { @@ -346,7 +346,7 @@ static struct mfd_cell stmpe_ts_cell = { }; /* - * STMPE811 + * STMPE811 or STMPE610 */ static const u8 stmpe811_regs[] = { @@ -417,6 +417,21 @@ static struct stmpe_variant_info stmpe811 = { .get_altfunc = stmpe811_get_altfunc, }; +/* Similar to 811, except number of gpios */ +static struct stmpe_variant_info stmpe610 = { + .name = "stmpe610", + .id_val = 0x0811, + .id_mask = 0xffff, + .num_gpios = 6, + .af_bits = 1, + .regs = stmpe811_regs, + .blocks = stmpe811_blocks, + .num_blocks = ARRAY_SIZE(stmpe811_blocks), + .num_irqs = STMPE811_NR_INTERNAL_IRQS, + .enable = stmpe811_enable, + .get_altfunc = stmpe811_get_altfunc, +}; + /* * STMPE1601 */ @@ -651,6 +666,7 @@ static struct stmpe_variant_info stmpe2403 = { }; static struct stmpe_variant_info *stmpe_variant_info[] = { + [STMPE610] = &stmpe610, [STMPE811] = &stmpe811, [STMPE1601] = &stmpe1601, [STMPE2401] = &stmpe2401, diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index babc6b2857d..342005afd34 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -20,6 +20,7 @@ enum stmpe_block { }; enum stmpe_partnum { + STMPE610, STMPE811, STMPE1601, STMPE2401, -- cgit v1.2.3-70-g09d2 From 7f7f4ea15ef4645f3888310a7a761fc2c4f689c9 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 17 Nov 2011 11:02:23 +0530 Subject: mfd: Add support for stmpe variant 801 STMPE801 is a GPIO expander. Registers for 801 are much different from other variants. This patch adds support for STMPE801 in stmpe mfd driver. Signed-off-by: Bhupesh Sharma Signed-off-by: Pratyush Anand Signed-off-by: Viresh Kumar Signed-off-by: Samuel Ortiz --- drivers/mfd/stmpe-i2c.c | 1 + drivers/mfd/stmpe-spi.c | 1 + drivers/mfd/stmpe.c | 97 ++++++++++++++++++++++++++++++++++++++++------- drivers/mfd/stmpe.h | 19 ++++++++++ include/linux/mfd/stmpe.h | 1 + 5 files changed, 106 insertions(+), 13 deletions(-) (limited to 'include/linux/mfd') diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index b11d33b1c89..373f423b118 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -72,6 +72,7 @@ static int __devexit stmpe_i2c_remove(struct i2c_client *i2c) static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe610", STMPE610 }, + { "stmpe801", STMPE801 }, { "stmpe811", STMPE811 }, { "stmpe1601", STMPE1601 }, { "stmpe2401", STMPE2401 }, diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index 46963a5d569..b58c43c7ea9 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c @@ -110,6 +110,7 @@ static int __devexit stmpe_spi_remove(struct spi_device *spi) static const struct spi_device_id stmpe_spi_id[] = { { "stmpe610", STMPE610 }, + { "stmpe801", STMPE801 }, { "stmpe811", STMPE811 }, { "stmpe1601", STMPE1601 }, { "stmpe2401", STMPE2401 }, diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 67ff3dc5bb4..fc2c6afb31e 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -241,12 +241,14 @@ int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block) u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB]; int af_bits = variant->af_bits; int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8); - int afperreg = 8 / af_bits; int mask = (1 << af_bits) - 1; u8 regs[numregs]; - int af; - int ret; + int af, afperreg, ret; + + if (!variant->get_altfunc) + return 0; + afperreg = 8 / af_bits; mutex_lock(&stmpe->lock); ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO); @@ -320,6 +322,50 @@ static struct mfd_cell stmpe_keypad_cell = { .num_resources = ARRAY_SIZE(stmpe_keypad_resources), }; +/* + * STMPE801 + */ +static const u8 stmpe801_regs[] = { + [STMPE_IDX_CHIP_ID] = STMPE801_REG_CHIP_ID, + [STMPE_IDX_ICR_LSB] = STMPE801_REG_SYS_CTRL, + [STMPE_IDX_GPMR_LSB] = STMPE801_REG_GPIO_MP_STA, + [STMPE_IDX_GPSR_LSB] = STMPE801_REG_GPIO_SET_PIN, + [STMPE_IDX_GPCR_LSB] = STMPE801_REG_GPIO_SET_PIN, + [STMPE_IDX_GPDR_LSB] = STMPE801_REG_GPIO_DIR, + [STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN, + [STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA, + +}; + +static struct stmpe_variant_block stmpe801_blocks[] = { + { + .cell = &stmpe_gpio_cell, + .irq = 0, + .block = STMPE_BLOCK_GPIO, + }, +}; + +static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks, + bool enable) +{ + if (blocks & STMPE_BLOCK_GPIO) + return 0; + else + return -EINVAL; +} + +static struct stmpe_variant_info stmpe801 = { + .name = "stmpe801", + .id_val = STMPE801_ID, + .id_mask = 0xffff, + .num_gpios = 8, + .regs = stmpe801_regs, + .blocks = stmpe801_blocks, + .num_blocks = ARRAY_SIZE(stmpe801_blocks), + .num_irqs = STMPE801_NR_INTERNAL_IRQS, + .enable = stmpe801_enable, +}; + /* * Touchscreen (STMPE811 or STMPE610) */ @@ -667,6 +713,7 @@ static struct stmpe_variant_info stmpe2403 = { static struct stmpe_variant_info *stmpe_variant_info[] = { [STMPE610] = &stmpe610, + [STMPE801] = &stmpe801, [STMPE811] = &stmpe811, [STMPE1601] = &stmpe1601, [STMPE2401] = &stmpe2401, @@ -683,6 +730,11 @@ static irqreturn_t stmpe_irq(int irq, void *data) int ret; int i; + if (variant->id_val == STMPE801_ID) { + handle_nested_irq(stmpe->irq_base); + return IRQ_HANDLED; + } + ret = stmpe_block_read(stmpe, israddr, num, isr); if (ret < 0) return IRQ_NONE; @@ -769,14 +821,17 @@ static struct irq_chip stmpe_irq_chip = { static int __devinit stmpe_irq_init(struct stmpe *stmpe) { + struct irq_chip *chip = NULL; int num_irqs = stmpe->variant->num_irqs; int base = stmpe->irq_base; int irq; + if (stmpe->variant->id_val != STMPE801_ID) + chip = &stmpe_irq_chip; + for (irq = base; irq < base + num_irqs; irq++) { irq_set_chip_data(irq, stmpe); - irq_set_chip_and_handler(irq, &stmpe_irq_chip, - handle_edge_irq); + irq_set_chip_and_handler(irq, chip, handle_edge_irq); irq_set_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); @@ -808,7 +863,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe) unsigned int irq_trigger = stmpe->pdata->irq_trigger; int autosleep_timeout = stmpe->pdata->autosleep_timeout; struct stmpe_variant_info *variant = stmpe->variant; - u8 icr = STMPE_ICR_LSB_GIM; + u8 icr; unsigned int id; u8 data[2]; int ret; @@ -831,16 +886,32 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe) if (ret) return ret; - if (irq_trigger == IRQF_TRIGGER_FALLING || - irq_trigger == IRQF_TRIGGER_RISING) - icr |= STMPE_ICR_LSB_EDGE; + if (id == STMPE801_ID) + icr = STMPE801_REG_SYS_CTRL_INT_EN; + else + icr = STMPE_ICR_LSB_GIM; + + /* STMPE801 doesn't support Edge interrupts */ + if (id != STMPE801_ID) { + if (irq_trigger == IRQF_TRIGGER_FALLING || + irq_trigger == IRQF_TRIGGER_RISING) + icr |= STMPE_ICR_LSB_EDGE; + } if (irq_trigger == IRQF_TRIGGER_RISING || - irq_trigger == IRQF_TRIGGER_HIGH) - icr |= STMPE_ICR_LSB_HIGH; + irq_trigger == IRQF_TRIGGER_HIGH) { + if (id == STMPE801_ID) + icr |= STMPE801_REG_SYS_CTRL_INT_HI; + else + icr |= STMPE_ICR_LSB_HIGH; + } - if (stmpe->pdata->irq_invert_polarity) - icr ^= STMPE_ICR_LSB_HIGH; + if (stmpe->pdata->irq_invert_polarity) { + if (id == STMPE801_ID) + icr ^= STMPE801_REG_SYS_CTRL_INT_HI; + else + icr ^= STMPE_ICR_LSB_HIGH; + } if (stmpe->pdata->autosleep) { ret = stmpe_autosleep(stmpe, autosleep_timeout); diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h index a73f4c1085f..7b8e13f5b76 100644 --- a/drivers/mfd/stmpe.h +++ b/drivers/mfd/stmpe.h @@ -104,6 +104,25 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE_ICR_LSB_EDGE (1 << 1) #define STMPE_ICR_LSB_GIM (1 << 0) +/* + * STMPE801 + */ +#define STMPE801_ID 0x0108 +#define STMPE801_NR_INTERNAL_IRQS 1 + +#define STMPE801_REG_CHIP_ID 0x00 +#define STMPE801_REG_VERSION_ID 0x02 +#define STMPE801_REG_SYS_CTRL 0x04 +#define STMPE801_REG_GPIO_INT_EN 0x08 +#define STMPE801_REG_GPIO_INT_STA 0x09 +#define STMPE801_REG_GPIO_MP_STA 0x10 +#define STMPE801_REG_GPIO_SET_PIN 0x11 +#define STMPE801_REG_GPIO_DIR 0x12 + +#define STMPE801_REG_SYS_CTRL_RESET (1 << 7) +#define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2) +#define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0) + /* * STMPE811 */ diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index 342005afd34..ca1d7a34760 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -21,6 +21,7 @@ enum stmpe_block { enum stmpe_partnum { STMPE610, + STMPE801, STMPE811, STMPE1601, STMPE2401, -- cgit v1.2.3-70-g09d2 From 0f5f70783eddde2bd277ae521fa04226cb1e249d Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Fri, 23 Dec 2011 17:28:08 +0900 Subject: mfd: Add S5M core driver S5M series are pmic including mutiple functional devices. It can support PMIC, RTC, Battery charger, codec. This patch implement core driver for s5m series. Signed-off-by: Sangbeom Kim Reviewed-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/s5m-core.c | 176 +++++++++++++++++ include/linux/mfd/s5m87xx/s5m-core.h | 373 +++++++++++++++++++++++++++++++++++ include/linux/mfd/s5m87xx/s5m-pmic.h | 100 ++++++++++ include/linux/mfd/s5m87xx/s5m-rtc.h | 84 ++++++++ 4 files changed, 733 insertions(+) create mode 100644 drivers/mfd/s5m-core.c create mode 100644 include/linux/mfd/s5m87xx/s5m-core.h create mode 100644 include/linux/mfd/s5m87xx/s5m-pmic.h create mode 100644 include/linux/mfd/s5m87xx/s5m-rtc.h (limited to 'include/linux/mfd') diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c new file mode 100644 index 00000000000..e075c113eec --- /dev/null +++ b/drivers/mfd/s5m-core.c @@ -0,0 +1,176 @@ +/* + * s5m87xx.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct mfd_cell s5m87xx_devs[] = { + { + .name = "s5m8767-pmic", + }, { + .name = "s5m-rtc", + }, +}; + +int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, void *dest) +{ + return regmap_read(s5m87xx->regmap, reg, dest); +} +EXPORT_SYMBOL_GPL(s5m_reg_read); + +int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf) +{ + return regmap_bulk_read(s5m87xx->regmap, reg, buf, count);; +} +EXPORT_SYMBOL_GPL(s5m_bulk_read); + +int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value) +{ + return regmap_write(s5m87xx->regmap, reg, value); +} +EXPORT_SYMBOL_GPL(s5m_reg_write); + +int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf) +{ + return regmap_raw_write(s5m87xx->regmap, reg, buf, count * sizeof(u16)); +} +EXPORT_SYMBOL_GPL(s5m_bulk_write); + +int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask) +{ + return regmap_update_bits(s5m87xx->regmap, reg, mask, val); +} +EXPORT_SYMBOL_GPL(s5m_reg_update); + +static struct regmap_config s5m_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int s5m87xx_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct s5m_platform_data *pdata = i2c->dev.platform_data; + struct s5m87xx_dev *s5m87xx; + int ret = 0; + int error; + + s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL); + if (s5m87xx == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, s5m87xx); + s5m87xx->dev = &i2c->dev; + s5m87xx->i2c = i2c; + s5m87xx->irq = i2c->irq; + s5m87xx->type = id->driver_data; + + if (pdata) { + s5m87xx->device_type = pdata->device_type; + s5m87xx->ono = pdata->ono; + s5m87xx->irq_base = pdata->irq_base; + s5m87xx->wakeup = pdata->wakeup; + } + + s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config); + if (IS_ERR(s5m87xx->regmap)) { + error = PTR_ERR(s5m87xx->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + error); + goto err; + } + + s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); + i2c_set_clientdata(s5m87xx->rtc, s5m87xx); + + if (pdata->cfg_pmic_irq) + pdata->cfg_pmic_irq(); + + s5m_irq_init(s5m87xx); + + pm_runtime_set_active(s5m87xx->dev); + + ret = mfd_add_devices(s5m87xx->dev, -1, + s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs), + NULL, 0); + + if (ret < 0) + goto err; + + return ret; + +err: + mfd_remove_devices(s5m87xx->dev); + s5m_irq_exit(s5m87xx); + i2c_unregister_device(s5m87xx->rtc); + regmap_exit(s5m87xx->regmap); + kfree(s5m87xx); + return ret; +} + +static int s5m87xx_i2c_remove(struct i2c_client *i2c) +{ + struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c); + + mfd_remove_devices(s5m87xx->dev); + s5m_irq_exit(s5m87xx); + i2c_unregister_device(s5m87xx->rtc); + regmap_exit(s5m87xx->regmap); + kfree(s5m87xx); + return 0; +} + +static const struct i2c_device_id s5m87xx_i2c_id[] = { + { "s5m87xx", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id); + +static struct i2c_driver s5m87xx_i2c_driver = { + .driver = { + .name = "s5m87xx", + .owner = THIS_MODULE, + }, + .probe = s5m87xx_i2c_probe, + .remove = s5m87xx_i2c_remove, + .id_table = s5m87xx_i2c_id, +}; + +static int __init s5m87xx_i2c_init(void) +{ + return i2c_add_driver(&s5m87xx_i2c_driver); +} + +subsys_initcall(s5m87xx_i2c_init); + +static void __exit s5m87xx_i2c_exit(void) +{ + i2c_del_driver(&s5m87xx_i2c_driver); +} +module_exit(s5m87xx_i2c_exit); + +MODULE_AUTHOR("Sangbeom Kim "); +MODULE_DESCRIPTION("Core support for the S5M MFD"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/s5m87xx/s5m-core.h b/include/linux/mfd/s5m87xx/s5m-core.h new file mode 100644 index 00000000000..a7480b57f92 --- /dev/null +++ b/include/linux/mfd/s5m87xx/s5m-core.h @@ -0,0 +1,373 @@ +/* + * s5m-core.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __LINUX_MFD_S5M_CORE_H +#define __LINUX_MFD_S5M_CORE_H + +#define NUM_IRQ_REGS 4 + +enum s5m_device_type { + S5M8751X, + S5M8763X, + S5M8767X, +}; + +/* S5M8767 registers */ +enum s5m8767_reg { + S5M8767_REG_ID, + S5M8767_REG_INT1, + S5M8767_REG_INT2, + S5M8767_REG_INT3, + S5M8767_REG_INT1M, + S5M8767_REG_INT2M, + S5M8767_REG_INT3M, + S5M8767_REG_STATUS1, + S5M8767_REG_STATUS2, + S5M8767_REG_STATUS3, + S5M8767_REG_CTRL1, + S5M8767_REG_CTRL2, + S5M8767_REG_LOWBAT1, + S5M8767_REG_LOWBAT2, + S5M8767_REG_BUCHG, + S5M8767_REG_DVSRAMP, + S5M8767_REG_DVSTIMER2 = 0x10, + S5M8767_REG_DVSTIMER3, + S5M8767_REG_DVSTIMER4, + S5M8767_REG_LDO1, + S5M8767_REG_LDO2, + S5M8767_REG_LDO3, + S5M8767_REG_LDO4, + S5M8767_REG_LDO5, + S5M8767_REG_LDO6, + S5M8767_REG_LDO7, + S5M8767_REG_LDO8, + S5M8767_REG_LDO9, + S5M8767_REG_LDO10, + S5M8767_REG_LDO11, + S5M8767_REG_LDO12, + S5M8767_REG_LDO13, + S5M8767_REG_LDO14 = 0x20, + S5M8767_REG_LDO15, + S5M8767_REG_LDO16, + S5M8767_REG_LDO17, + S5M8767_REG_LDO18, + S5M8767_REG_LDO19, + S5M8767_REG_LDO20, + S5M8767_REG_LDO21, + S5M8767_REG_LDO22, + S5M8767_REG_LDO23, + S5M8767_REG_LDO24, + S5M8767_REG_LDO25, + S5M8767_REG_LDO26, + S5M8767_REG_LDO27, + S5M8767_REG_LDO28, + S5M8767_REG_UVLO = 0x31, + S5M8767_REG_BUCK1CTRL1, + S5M8767_REG_BUCK1CTRL2, + S5M8767_REG_BUCK2CTRL, + S5M8767_REG_BUCK2DVS1, + S5M8767_REG_BUCK2DVS2, + S5M8767_REG_BUCK2DVS3, + S5M8767_REG_BUCK2DVS4, + S5M8767_REG_BUCK2DVS5, + S5M8767_REG_BUCK2DVS6, + S5M8767_REG_BUCK2DVS7, + S5M8767_REG_BUCK2DVS8, + S5M8767_REG_BUCK3CTRL, + S5M8767_REG_BUCK3DVS1, + S5M8767_REG_BUCK3DVS2, + S5M8767_REG_BUCK3DVS3, + S5M8767_REG_BUCK3DVS4, + S5M8767_REG_BUCK3DVS5, + S5M8767_REG_BUCK3DVS6, + S5M8767_REG_BUCK3DVS7, + S5M8767_REG_BUCK3DVS8, + S5M8767_REG_BUCK4CTRL, + S5M8767_REG_BUCK4DVS1, + S5M8767_REG_BUCK4DVS2, + S5M8767_REG_BUCK4DVS3, + S5M8767_REG_BUCK4DVS4, + S5M8767_REG_BUCK4DVS5, + S5M8767_REG_BUCK4DVS6, + S5M8767_REG_BUCK4DVS7, + S5M8767_REG_BUCK4DVS8, + S5M8767_REG_BUCK5CTRL1, + S5M8767_REG_BUCK5CTRL2, + S5M8767_REG_BUCK5CTRL3, + S5M8767_REG_BUCK5CTRL4, + S5M8767_REG_BUCK5CTRL5, + S5M8767_REG_BUCK6CTRL1, + S5M8767_REG_BUCK6CTRL2, + S5M8767_REG_BUCK7CTRL1, + S5M8767_REG_BUCK7CTRL2, + S5M8767_REG_BUCK8CTRL1, + S5M8767_REG_BUCK8CTRL2, + S5M8767_REG_BUCK9CTRL1, + S5M8767_REG_BUCK9CTRL2, + S5M8767_REG_LDO1CTRL, + S5M8767_REG_LDO2_1CTRL, + S5M8767_REG_LDO2_2CTRL, + S5M8767_REG_LDO2_3CTRL, + S5M8767_REG_LDO2_4CTRL, + S5M8767_REG_LDO3CTRL, + S5M8767_REG_LDO4CTRL, + S5M8767_REG_LDO5CTRL, + S5M8767_REG_LDO6CTRL, + S5M8767_REG_LDO7CTRL, + S5M8767_REG_LDO8CTRL, + S5M8767_REG_LDO9CTRL, + S5M8767_REG_LDO10CTRL, + S5M8767_REG_LDO11CTRL, + S5M8767_REG_LDO12CTRL, + S5M8767_REG_LDO13CTRL, + S5M8767_REG_LDO14CTRL, + S5M8767_REG_LDO15CTRL, + S5M8767_REG_LDO16CTRL, + S5M8767_REG_LDO17CTRL, + S5M8767_REG_LDO18CTRL, + S5M8767_REG_LDO19CTRL, + S5M8767_REG_LDO20CTRL, + S5M8767_REG_LDO21CTRL, + S5M8767_REG_LDO22CTRL, + S5M8767_REG_LDO23CTRL, + S5M8767_REG_LDO24CTRL, + S5M8767_REG_LDO25CTRL, + S5M8767_REG_LDO26CTRL, + S5M8767_REG_LDO27CTRL, + S5M8767_REG_LDO28CTRL, +}; + +/* S5M8763 registers */ +enum s5m8763_reg { + S5M8763_REG_IRQ1, + S5M8763_REG_IRQ2, + S5M8763_REG_IRQ3, + S5M8763_REG_IRQ4, + S5M8763_REG_IRQM1, + S5M8763_REG_IRQM2, + S5M8763_REG_IRQM3, + S5M8763_REG_IRQM4, + S5M8763_REG_STATUS1, + S5M8763_REG_STATUS2, + S5M8763_REG_STATUSM1, + S5M8763_REG_STATUSM2, + S5M8763_REG_CHGR1, + S5M8763_REG_CHGR2, + S5M8763_REG_LDO_ACTIVE_DISCHARGE1, + S5M8763_REG_LDO_ACTIVE_DISCHARGE2, + S5M8763_REG_BUCK_ACTIVE_DISCHARGE3, + S5M8763_REG_ONOFF1, + S5M8763_REG_ONOFF2, + S5M8763_REG_ONOFF3, + S5M8763_REG_ONOFF4, + S5M8763_REG_BUCK1_VOLTAGE1, + S5M8763_REG_BUCK1_VOLTAGE2, + S5M8763_REG_BUCK1_VOLTAGE3, + S5M8763_REG_BUCK1_VOLTAGE4, + S5M8763_REG_BUCK2_VOLTAGE1, + S5M8763_REG_BUCK2_VOLTAGE2, + S5M8763_REG_BUCK3, + S5M8763_REG_BUCK4, + S5M8763_REG_LDO1_LDO2, + S5M8763_REG_LDO3, + S5M8763_REG_LDO4, + S5M8763_REG_LDO5, + S5M8763_REG_LDO6, + S5M8763_REG_LDO7, + S5M8763_REG_LDO7_LDO8, + S5M8763_REG_LDO9_LDO10, + S5M8763_REG_LDO11, + S5M8763_REG_LDO12, + S5M8763_REG_LDO13, + S5M8763_REG_LDO14, + S5M8763_REG_LDO15, + S5M8763_REG_LDO16, + S5M8763_REG_BKCHR, + S5M8763_REG_LBCNFG1, + S5M8763_REG_LBCNFG2, +}; + +enum s5m8767_irq { + S5M8767_IRQ_PWRR, + S5M8767_IRQ_PWRF, + S5M8767_IRQ_PWR1S, + S5M8767_IRQ_JIGR, + S5M8767_IRQ_JIGF, + S5M8767_IRQ_LOWBAT2, + S5M8767_IRQ_LOWBAT1, + + S5M8767_IRQ_MRB, + S5M8767_IRQ_DVSOK2, + S5M8767_IRQ_DVSOK3, + S5M8767_IRQ_DVSOK4, + + S5M8767_IRQ_RTC60S, + S5M8767_IRQ_RTCA1, + S5M8767_IRQ_RTCA2, + S5M8767_IRQ_SMPL, + S5M8767_IRQ_RTC1S, + S5M8767_IRQ_WTSR, + + S5M8767_IRQ_NR, +}; + +#define S5M8767_IRQ_PWRR_MASK (1 << 0) +#define S5M8767_IRQ_PWRF_MASK (1 << 1) +#define S5M8767_IRQ_PWR1S_MASK (1 << 3) +#define S5M8767_IRQ_JIGR_MASK (1 << 4) +#define S5M8767_IRQ_JIGF_MASK (1 << 5) +#define S5M8767_IRQ_LOWBAT2_MASK (1 << 6) +#define S5M8767_IRQ_LOWBAT1_MASK (1 << 7) + +#define S5M8767_IRQ_MRB_MASK (1 << 2) +#define S5M8767_IRQ_DVSOK2_MASK (1 << 3) +#define S5M8767_IRQ_DVSOK3_MASK (1 << 4) +#define S5M8767_IRQ_DVSOK4_MASK (1 << 5) + +#define S5M8767_IRQ_RTC60S_MASK (1 << 0) +#define S5M8767_IRQ_RTCA1_MASK (1 << 1) +#define S5M8767_IRQ_RTCA2_MASK (1 << 2) +#define S5M8767_IRQ_SMPL_MASK (1 << 3) +#define S5M8767_IRQ_RTC1S_MASK (1 << 4) +#define S5M8767_IRQ_WTSR_MASK (1 << 5) + +enum s5m8763_irq { + S5M8763_IRQ_DCINF, + S5M8763_IRQ_DCINR, + S5M8763_IRQ_JIGF, + S5M8763_IRQ_JIGR, + S5M8763_IRQ_PWRONF, + S5M8763_IRQ_PWRONR, + + S5M8763_IRQ_WTSREVNT, + S5M8763_IRQ_SMPLEVNT, + S5M8763_IRQ_ALARM1, + S5M8763_IRQ_ALARM0, + + S5M8763_IRQ_ONKEY1S, + S5M8763_IRQ_TOPOFFR, + S5M8763_IRQ_DCINOVPR, + S5M8763_IRQ_CHGRSTF, + S5M8763_IRQ_DONER, + S5M8763_IRQ_CHGFAULT, + + S5M8763_IRQ_LOBAT1, + S5M8763_IRQ_LOBAT2, + + S5M8763_IRQ_NR, +}; + +#define S5M8763_IRQ_DCINF_MASK (1 << 2) +#define S5M8763_IRQ_DCINR_MASK (1 << 3) +#define S5M8763_IRQ_JIGF_MASK (1 << 4) +#define S5M8763_IRQ_JIGR_MASK (1 << 5) +#define S5M8763_IRQ_PWRONF_MASK (1 << 6) +#define S5M8763_IRQ_PWRONR_MASK (1 << 7) + +#define S5M8763_IRQ_WTSREVNT_MASK (1 << 0) +#define S5M8763_IRQ_SMPLEVNT_MASK (1 << 1) +#define S5M8763_IRQ_ALARM1_MASK (1 << 2) +#define S5M8763_IRQ_ALARM0_MASK (1 << 3) + +#define S5M8763_IRQ_ONKEY1S_MASK (1 << 0) +#define S5M8763_IRQ_TOPOFFR_MASK (1 << 2) +#define S5M8763_IRQ_DCINOVPR_MASK (1 << 3) +#define S5M8763_IRQ_CHGRSTF_MASK (1 << 4) +#define S5M8763_IRQ_DONER_MASK (1 << 5) +#define S5M8763_IRQ_CHGFAULT_MASK (1 << 7) + +#define S5M8763_IRQ_LOBAT1_MASK (1 << 0) +#define S5M8763_IRQ_LOBAT2_MASK (1 << 1) + +#define S5M8763_ENRAMP (1 << 4) + +/** + * struct s5m87xx_dev - s5m87xx master device for sub-drivers + * @dev: master device of the chip (can be used to access platform data) + * @i2c: i2c client private data for regulator + * @rtc: i2c client private data for rtc + * @iolock: mutex for serializing io access + * @irqlock: mutex for buslock + * @irq_base: base IRQ number for s5m87xx, required for IRQs + * @irq: generic IRQ number for s5m87xx + * @ono: power onoff IRQ number for s5m87xx + * @irq_masks_cur: currently active value + * @irq_masks_cache: cached hardware value + * @type: indicate which s5m87xx "variant" is used + */ +struct s5m87xx_dev { + struct device *dev; + struct regmap *regmap; + struct i2c_client *i2c; + struct i2c_client *rtc; + struct mutex iolock; + struct mutex irqlock; + + int device_type; + int irq_base; + int irq; + int ono; + u8 irq_masks_cur[NUM_IRQ_REGS]; + u8 irq_masks_cache[NUM_IRQ_REGS]; + int type; + bool wakeup; +}; + +int s5m_irq_init(struct s5m87xx_dev *s5m87xx); +void s5m_irq_exit(struct s5m87xx_dev *s5m87xx); +int s5m_irq_resume(struct s5m87xx_dev *s5m87xx); + +extern int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, void *dest); +extern int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf); +extern int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value); +extern int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf); +extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask); + +struct s5m_platform_data { + struct s5m_regulator_data *regulators; + int device_type; + int num_regulators; + + int irq_base; + int (*cfg_pmic_irq)(void); + + int ono; + bool wakeup; + bool buck_voltage_lock; + + int buck_gpios[3]; + int buck2_voltage[8]; + bool buck2_gpiodvs; + int buck3_voltage[8]; + bool buck3_gpiodvs; + int buck4_voltage[8]; + bool buck4_gpiodvs; + + int buck_set1; + int buck_set2; + int buck_set3; + int buck2_enable; + int buck3_enable; + int buck4_enable; + int buck_default_idx; + int buck2_default_idx; + int buck3_default_idx; + int buck4_default_idx; + + int buck_ramp_delay; + bool buck2_ramp_enable; + bool buck3_ramp_enable; + bool buck4_ramp_enable; +}; + +#endif /* __LINUX_MFD_S5M_CORE_H */ diff --git a/include/linux/mfd/s5m87xx/s5m-pmic.h b/include/linux/mfd/s5m87xx/s5m-pmic.h new file mode 100644 index 00000000000..a72a5d27e62 --- /dev/null +++ b/include/linux/mfd/s5m87xx/s5m-pmic.h @@ -0,0 +1,100 @@ +/* s5m87xx.h + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * 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. +*/ + +#ifndef __LINUX_MFD_S5M_PMIC_H +#define __LINUX_MFD_S5M_PMIC_H + +#include + +/* S5M8767 regulator ids */ +enum s5m8767_regulators { + S5M8767_LDO1, + S5M8767_LDO2, + S5M8767_LDO3, + S5M8767_LDO4, + S5M8767_LDO5, + S5M8767_LDO6, + S5M8767_LDO7, + S5M8767_LDO8, + S5M8767_LDO9, + S5M8767_LDO10, + S5M8767_LDO11, + S5M8767_LDO12, + S5M8767_LDO13, + S5M8767_LDO14, + S5M8767_LDO15, + S5M8767_LDO16, + S5M8767_LDO17, + S5M8767_LDO18, + S5M8767_LDO19, + S5M8767_LDO20, + S5M8767_LDO21, + S5M8767_LDO22, + S5M8767_LDO23, + S5M8767_LDO24, + S5M8767_LDO25, + S5M8767_LDO26, + S5M8767_LDO27, + S5M8767_LDO28, + S5M8767_BUCK1, + S5M8767_BUCK2, + S5M8767_BUCK3, + S5M8767_BUCK4, + S5M8767_BUCK5, + S5M8767_BUCK6, + S5M8767_BUCK7, + S5M8767_BUCK8, + S5M8767_BUCK9, + S5M8767_AP_EN32KHZ, + S5M8767_CP_EN32KHZ, + + S5M8767_REG_MAX, +}; + +/* S5M8763 regulator ids */ +enum s5m8763_regulators { + S5M8763_LDO1, + S5M8763_LDO2, + S5M8763_LDO3, + S5M8763_LDO4, + S5M8763_LDO5, + S5M8763_LDO6, + S5M8763_LDO7, + S5M8763_LDO8, + S5M8763_LDO9, + S5M8763_LDO10, + S5M8763_LDO11, + S5M8763_LDO12, + S5M8763_LDO13, + S5M8763_LDO14, + S5M8763_LDO15, + S5M8763_LDO16, + S5M8763_BUCK1, + S5M8763_BUCK2, + S5M8763_BUCK3, + S5M8763_BUCK4, + S5M8763_AP_EN32KHZ, + S5M8763_CP_EN32KHZ, + S5M8763_ENCHGVI, + S5M8763_ESAFEUSB1, + S5M8763_ESAFEUSB2, +}; + +/** + * s5m87xx_regulator_data - regulator data + * @id: regulator id + * @initdata: regulator init data (contraints, supplies, ...) + */ +struct s5m_regulator_data { + int id; + struct regulator_init_data *initdata; +}; + +#endif /* __LINUX_MFD_S5M_PMIC_H */ diff --git a/include/linux/mfd/s5m87xx/s5m-rtc.h b/include/linux/mfd/s5m87xx/s5m-rtc.h new file mode 100644 index 00000000000..6ce8da264ce --- /dev/null +++ b/include/linux/mfd/s5m87xx/s5m-rtc.h @@ -0,0 +1,84 @@ +/* + * s5m-rtc.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __LINUX_MFD_S5M_RTC_H +#define __LINUX_MFD_S5M_RTC_H + +enum s5m87xx_rtc_reg { + S5M87XX_RTC_SEC, + S5M87XX_RTC_MIN, + S5M87XX_RTC_HOUR, + S5M87XX_RTC_WEEKDAY, + S5M87XX_RTC_DATE, + S5M87XX_RTC_MONTH, + S5M87XX_RTC_YEAR1, + S5M87XX_RTC_YEAR2, + S5M87XX_ALARM0_SEC, + S5M87XX_ALARM0_MIN, + S5M87XX_ALARM0_HOUR, + S5M87XX_ALARM0_WEEKDAY, + S5M87XX_ALARM0_DATE, + S5M87XX_ALARM0_MONTH, + S5M87XX_ALARM0_YEAR1, + S5M87XX_ALARM0_YEAR2, + S5M87XX_ALARM1_SEC, + S5M87XX_ALARM1_MIN, + S5M87XX_ALARM1_HOUR, + S5M87XX_ALARM1_WEEKDAY, + S5M87XX_ALARM1_DATE, + S5M87XX_ALARM1_MONTH, + S5M87XX_ALARM1_YEAR1, + S5M87XX_ALARM1_YEAR2, + S5M87XX_ALARM0_CONF, + S5M87XX_ALARM1_CONF, + S5M87XX_RTC_STATUS, + S5M87XX_WTSR_SMPL_CNTL, + S5M87XX_RTC_UDR_CON, +}; + +#define RTC_I2C_ADDR (0x0C >> 1) + +#define HOUR_12 (1 << 7) +#define HOUR_AMPM (1 << 6) +#define HOUR_PM (1 << 5) +#define ALARM0_STATUS (1 << 1) +#define ALARM1_STATUS (1 << 2) +#define UPDATE_AD (1 << 0) + +/* RTC Control Register */ +#define BCD_EN_SHIFT 0 +#define BCD_EN_MASK (1 << BCD_EN_SHIFT) +#define MODEL24_SHIFT 1 +#define MODEL24_MASK (1 << MODEL24_SHIFT) +/* RTC Update Register1 */ +#define RTC_UDR_SHIFT 0 +#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) +/* RTC Hour register */ +#define HOUR_PM_SHIFT 6 +#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) +/* RTC Alarm Enable */ +#define ALARM_ENABLE_SHIFT 7 +#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) + +enum { + RTC_SEC = 0, + RTC_MIN, + RTC_HOUR, + RTC_WEEKDAY, + RTC_DATE, + RTC_MONTH, + RTC_YEAR1, + RTC_YEAR2, +}; + +#endif /* __LINUX_MFD_S5M_RTC_H */ -- cgit v1.2.3-70-g09d2 From ba74e80ebaf8209cb553eb2195b26302270cfa42 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 4 Jan 2012 15:14:24 +0800 Subject: mfd: Add pm ops to max8925 Signed-off-by: Kevin Liu Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/mfd/max8925-i2c.c | 27 +++++++++++++++++++++++++++ include/linux/mfd/max8925.h | 2 ++ 2 files changed, 29 insertions(+) (limited to 'include/linux/mfd') diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 0219115e00c..d9e4b36edee 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -161,6 +161,8 @@ static int __devinit max8925_probe(struct i2c_client *client, chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); i2c_set_clientdata(chip->adc, chip); + device_init_wakeup(&client->dev, 1); + max8925_device_init(chip, pdata); return 0; @@ -177,10 +179,35 @@ static int __devexit max8925_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM_SLEEP +static int max8925_suspend(struct device *dev) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct max8925_chip *chip = i2c_get_clientdata(client); + + if (device_may_wakeup(dev) && chip->wakeup_flag) + enable_irq_wake(chip->core_irq); + return 0; +} + +static int max8925_resume(struct device *dev) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + struct max8925_chip *chip = i2c_get_clientdata(client); + + if (device_may_wakeup(dev) && chip->wakeup_flag) + disable_irq_wake(chip->core_irq); + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume); + static struct i2c_driver max8925_driver = { .driver = { .name = "max8925", .owner = THIS_MODULE, + .pm = &max8925_pm_ops, }, .probe = max8925_probe, .remove = __devexit_p(max8925_remove), diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h index 5259dfe8c58..daaba00f0bc 100644 --- a/include/linux/mfd/max8925.h +++ b/include/linux/mfd/max8925.h @@ -206,6 +206,8 @@ struct max8925_chip { int irq_base; int core_irq; int tsc_irq; + + unsigned int wakeup_flag; }; struct max8925_backlight_pdata { -- cgit v1.2.3-70-g09d2