Commit 30304e5a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mfd_3.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6

Pull MFD changes from Samuel Ortiz:
 - 4 new drivers: Freescale i.MX on-chip Anatop, Ricoh's RC5T583 and
   TI's TPS65090 and TPS65217.
 - New variants support (8420, 8520 ab9540), cleanups and bug fixes for
   the abx500 and db8500 ST-E chipsets.
 - Some minor fixes and update for the wm8994 from Mark.
 - The beginning of a long term TWL cleanup effort coming from the TI
   folks.
 - Various fixes and cleanups for the s5m, TPS659xx, pm860x, and MAX8997
   drivers.

Fix up trivial conflicts due to duplicate patches and header file
cleanups (<linux/device.h> removal etc).

* tag 'mfd_3.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (97 commits)
  gpio/twl: Add DT support to gpio-twl4030 driver
  gpio/twl: Allocate irq_desc dynamically for SPARSE_IRQ support
  mfd: Detach twl6040 from the pmic mfd driver
  mfd: Replace twl-* pr_ macros by the dev_ equivalent and do various cleanups
  mfd: Micro-optimization on twl4030 IRQ handler
  mfd: Make twl4030 SIH SPARSE_IRQ capable
  mfd: Move twl-core IRQ allocation into twl[4030|6030]-irq files
  mfd: Remove references already defineid in header file from twl-core
  mfd: Remove unneeded header from twl-core
  mfd: Make twl-core not depend on pdata->irq_base/end
  ARM: OMAP2+: board-omap4-*: Do not use anymore TWL6030_IRQ_BASE in board files
  mfd: Return twl6030_mmc_card_detect IRQ for board setup
  Revert "mfd: Add platform data for MAX8997 haptic driver"
  mfd: Add support for TPS65090
  mfd: Add some da9052-i2c section annotations
  mfd: Build rtc5t583 only if I2C config is selected to y.
  mfd: Add anatop mfd driver
  mfd: Fix compilation error in tps65910.h
  mfd: Add 8420 variant to db8500-prcmu
  mfd: Add 8520 PRCMU variant to db8500-prcmu
  ...
parents 750f7706 b8589e2a
twl4030 GPIO controller bindings
Required properties:
- compatible:
- "ti,twl4030-gpio" for twl4030 GPIO controller
- #gpio-cells : Should be two.
- first cell is the pin number
- second cell is used to specify optional parameters (unused)
- gpio-controller : Marks the device node as a GPIO controller.
- #interrupt-cells : Should be 2.
- interrupt-controller: Mark the device node as an interrupt controller
The first cell is the GPIO number.
The second cell is not used.
Example:
twl_gpio: gpio {
compatible = "ti,twl4030-gpio";
#gpio-cells = <2>;
gpio-controller;
#interrupt-cells = <2>;
interrupt-controller;
};
......@@ -490,21 +490,22 @@ static struct platform_device omap_vwlan_device = {
static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
int ret = 0;
int irq = 0;
struct platform_device *pdev = container_of(dev,
struct platform_device, dev);
struct omap_mmc_platform_data *pdata = dev->platform_data;
/* Setting MMC1 Card detect Irq */
if (pdev->id == 0) {
ret = twl6030_mmc_card_detect_config();
if (ret)
irq = twl6030_mmc_card_detect_config();
if (irq < 0) {
pr_err("Failed configuring MMC1 card detect\n");
pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
MMCDETECT_INTR_OFFSET;
return irq;
}
pdata->slots[0].card_detect_irq = irq;
pdata->slots[0].card_detect = twl6030_mmc_card_detect;
}
return ret;
return 0;
}
static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
......
......@@ -238,7 +238,7 @@ struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
int ret = 0;
int irq = 0;
struct platform_device *pdev = container_of(dev,
struct platform_device, dev);
struct omap_mmc_platform_data *pdata = dev->platform_data;
......@@ -249,14 +249,15 @@ static int omap4_twl6030_hsmmc_late_init(struct device *dev)
}
/* Setting MMC1 Card detect Irq */
if (pdev->id == 0) {
ret = twl6030_mmc_card_detect_config();
if (ret)
irq = twl6030_mmc_card_detect_config();
if (irq < 0) {
dev_err(dev, "%s: Error card detect config(%d)\n",
__func__, ret);
else
__func__, irq);
return irq;
}
pdata->slots[0].card_detect = twl6030_mmc_card_detect;
}
return ret;
return 0;
}
static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
......
......@@ -17,6 +17,8 @@
#include <linux/mfd/wm831x/gpio.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/regulator/machine.h>
#include <sound/wm5100.h>
#include <sound/wm8996.h>
#include <sound/wm8962.h>
......@@ -153,6 +155,14 @@ static const struct i2c_board_info wm1259_devs[] = {
},
};
static struct regulator_init_data wm8994_ldo1 = {
.supply_regulator = "WALLVDD",
};
static struct regulator_init_data wm8994_ldo2 = {
.supply_regulator = "WALLVDD",
};
static struct wm8994_pdata wm8994_pdata = {
.gpio_base = CODEC_GPIO_BASE,
.gpio_defaults = {
......@@ -160,8 +170,8 @@ static struct wm8994_pdata wm8994_pdata = {
},
.irq_base = CODEC_IRQ_BASE,
.ldo = {
{ .supply = "WALLVDD" },
{ .supply = "WALLVDD" },
{ .init_data = &wm8994_ldo1, },
{ .init_data = &wm8994_ldo2, },
},
};
......
......@@ -13,7 +13,7 @@
#define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START
#define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \
+ AB8500_NR_IRQS)
+ AB8500_MAX_NR_IRQS)
/* TC35892 */
#define TC35892_NR_INTERNAL_IRQS 8
......
......@@ -22,11 +22,11 @@ static struct cpufreq_frequency_table freq_table[] = {
},
[1] = {
.index = 1,
.frequency = 300000,
.frequency = 400000,
},
[2] = {
.index = 2,
.frequency = 600000,
.frequency = 800000,
},
[3] = {
/* Used for MAX_OPP, if available */
......@@ -113,12 +113,9 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table));
if (!prcmu_is_u8400()) {
freq_table[1].frequency = 400000;
freq_table[2].frequency = 800000;
if (prcmu_has_arm_maxopp())
freq_table[3].frequency = 1000000;
}
pr_info("db8500-cpufreq : Available frequencies:\n");
for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
pr_info(" %d Mhz\n", freq_table[i].frequency/1000);
......
......@@ -307,13 +307,11 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
struct stmpe_gpio_platform_data *pdata;
struct stmpe_gpio *stmpe_gpio;
int ret;
int irq;
int irq = 0;
pdata = stmpe->pdata->gpio;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
stmpe_gpio = kzalloc(sizeof(struct stmpe_gpio), GFP_KERNEL);
if (!stmpe_gpio)
......@@ -330,22 +328,29 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
stmpe_gpio->chip.dev = &pdev->dev;
stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1;
if (irq >= 0)
stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0);
else
dev_info(&pdev->dev,
"device configured in no-irq mode; "
"irqs are not available\n");
ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
if (ret)
goto out_free;
if (irq >= 0) {
ret = stmpe_gpio_irq_init(stmpe_gpio);
if (ret)
goto out_disable;
ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT,
"stmpe-gpio", stmpe_gpio);
ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq,
IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio);
if (ret) {
dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
goto out_removeirq;
}
}
ret = gpiochip_add(&stmpe_gpio->chip);
if (ret) {
......@@ -361,8 +366,10 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
return 0;
out_freeirq:
if (irq >= 0)
free_irq(irq, stmpe_gpio);
out_removeirq:
if (irq >= 0)
stmpe_gpio_irq_remove(stmpe_gpio);
out_disable:
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
......@@ -391,8 +398,10 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev)
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
if (irq >= 0) {
free_irq(irq, stmpe_gpio);
stmpe_gpio_irq_remove(stmpe_gpio);
}
platform_set_drvdata(pdev, NULL);
kfree(stmpe_gpio);
......
......@@ -32,6 +32,8 @@
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/irqdomain.h>
#include <linux/i2c/twl.h>
......@@ -256,6 +258,7 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
* and vMMC2 power supplies based on card presence.
*/
pdata = chip->dev->platform_data;
if (pdata)
value |= pdata->mmc_cd & 0x03;
status = gpio_twl4030_write(REG_GPIO_CTRL, value);
......@@ -395,23 +398,38 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
{
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
int ret;
struct device_node *node = pdev->dev.of_node;
int ret, irq_base;
/* maybe setup IRQs */
if (pdata->irq_base) {
if (is_module()) {
dev_err(&pdev->dev,
"can't dispatch IRQs from modules\n");
dev_err(&pdev->dev, "can't dispatch IRQs from modules\n");
goto no_irqs;
}
ret = twl4030_sih_setup(TWL4030_MODULE_GPIO);
irq_base = irq_alloc_descs(-1, 0, TWL4030_GPIO_MAX, 0);
if (irq_base < 0) {
dev_err(&pdev->dev, "Failed to alloc irq_descs\n");
return irq_base;
}
irq_domain_add_legacy(node, TWL4030_GPIO_MAX, irq_base, 0,
&irq_domain_simple_ops, NULL);
ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
if (ret < 0)
return ret;
WARN_ON(ret != pdata->irq_base);
twl4030_gpio_irq_base = ret;
}
twl4030_gpio_irq_base = irq_base;
no_irqs:
twl_gpiochip.base = -1;
twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
twl_gpiochip.dev = &pdev->dev;
if (pdata) {
twl_gpiochip.base = pdata->gpio_base;
/*
* NOTE: boards may waste power if they don't set pullups
* and pulldowns correctly ... default for non-ULPI pins is
......@@ -430,24 +448,20 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
pdata->debounce, pdata->mmc_cd,
ret);
twl_gpiochip.base = pdata->gpio_base;
twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
twl_gpiochip.dev = &pdev->dev;
/* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
/*
* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
* is (still) clear if use_leds is set.
*/
if (pdata->use_leds)
twl_gpiochip.ngpio += 2;
}
ret = gpiochip_add(&twl_gpiochip);
if (ret < 0) {
dev_err(&pdev->dev,
"could not register gpiochip, %d\n",
ret);
dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
twl_gpiochip.ngpio = 0;
gpio_twl4030_remove(pdev);
} else if (pdata->setup) {
} else if (pdata && pdata->setup) {
int status;
status = pdata->setup(&pdev->dev,
......@@ -465,7 +479,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
int status;
if (pdata->teardown) {
if (pdata && pdata->teardown) {
status = pdata->teardown(&pdev->dev,
pdata->gpio_base, TWL4030_GPIO_MAX);
if (status) {
......@@ -486,12 +500,21 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
return -EIO;
}
static const struct of_device_id twl_gpio_match[] = {
{ .compatible = "ti,twl4030-gpio", },
{ },
};
MODULE_DEVICE_TABLE(of, twl_gpio_match);
/* Note: this hardware lives inside an I2C-based multi-function device. */
MODULE_ALIAS("platform:twl4030_gpio");
static struct platform_driver gpio_twl4030_driver = {
.driver.name = "twl4030_gpio",
.driver.owner = THIS_MODULE,
.driver = {
.name = "twl4030_gpio",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(twl_gpio_match),
},
.probe = gpio_twl4030_probe,
.remove = gpio_twl4030_remove,
};
......
......@@ -59,7 +59,7 @@ static int mc13783_adc_read(struct device *dev,
ret = mc13xxx_adc_do_conversion(priv->mc13xxx,
MC13XXX_ADC_MODE_MULT_CHAN,
channel, sample);
channel, 0, 0, sample);
if (ret)
return ret;
......
......@@ -105,6 +105,8 @@ static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, info);
device_init_wakeup(&pdev->dev, 1);
return 0;
out_irq:
......@@ -129,10 +131,34 @@ static int __devexit pm860x_onkey_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int pm860x_onkey_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
if (device_may_wakeup(dev))
chip->wakeup_flag |= 1 << PM8607_IRQ_ONKEY;
return 0;
}
static int pm860x_onkey_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
if (device_may_wakeup(dev))
chip->wakeup_flag &= ~(1 << PM8607_IRQ_ONKEY);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(pm860x_onkey_pm_ops, pm860x_onkey_suspend, pm860x_onkey_resume);
static struct platform_driver pm860x_onkey_driver = {
.driver = {
.name = "88pm860x-onkey",
.owner = THIS_MODULE,
.pm = &pm860x_onkey_pm_ops,
},
.probe = pm860x_onkey_probe,
.remove = __devexit_p(pm860x_onkey_remove),
......
......@@ -39,6 +39,7 @@ struct mc13783_ts_priv {
struct delayed_work work;
struct workqueue_struct *workq;
unsigned int sample[4];
struct mc13xxx_ts_platform_data *touch;
};
static irqreturn_t mc13783_ts_handler(int irq, void *data)
......@@ -125,7 +126,9 @@ static void mc13783_ts_work(struct work_struct *work)
unsigned int channel = 12;
if (mc13xxx_adc_do_conversion(priv->mc13xxx,
mode, channel, priv->sample) == 0)
mode, channel,
priv->touch->ato, priv->touch->atox,
priv->sample) == 0)
mc13783_ts_report_sample(priv);
}
......@@ -179,6 +182,12 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
priv->idev = idev;
priv->touch = dev_get_platdata(&pdev->dev);
if (!priv->touch) {
dev_err(&pdev->dev, "missing platform data\n");
ret = -ENODEV;
goto err_free_mem;
}
/*
* We need separate workqueue because mc13783_adc_do_conversion
......
......@@ -114,6 +114,27 @@ static inline int __blink_ctl_mask(int port)
return ret;
}
static int led_power_set(struct pm860x_chip *chip, int port, int on)
{
int ret = -EINVAL;
switch (port) {
case PM8606_LED1_RED:
case PM8606_LED1_GREEN:
case PM8606_LED1_BLUE:
ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) :
pm8606_osc_disable(chip, RGB1_ENABLE);
break;
case PM8606_LED2_RED:
case PM8606_LED2_GREEN:
case PM8606_LED2_BLUE:
ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) :
pm8606_osc_disable(chip, RGB2_ENABLE);
break;
}
return ret;
}
static void pm860x_led_work(struct work_struct *work)
{
......@@ -126,6 +147,7 @@ static void pm860x_led_work(struct work_struct *work)
chip = led->chip;
mutex_lock(&led->lock);
if ((led->current_brightness == 0) && led->brightness) {
led_power_set(chip, led->port, 1);
if (led->iset) {
pm860x_set_bits(led->i2c, __led_off(led->port),
LED_CURRENT_MASK, led->iset);
......@@ -149,6 +171,7 @@ static void pm860x_led_work(struct work_struct *work)
LED_CURRENT_MASK, 0);
mask = __blink_ctl_mask(led->port);
pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
led_power_set(chip, led->port, 0);
}
}
led->current_brightness = led->brightness;
......
......@@ -503,6 +503,101 @@ static void device_irq_exit(struct pm860x_chip *chip)
free_irq(chip->core_irq, chip);
}
int pm8606_osc_enable(struct pm860x_chip *chip, unsigned short client)
{
int ret = -EIO;
struct i2c_client *i2c = (chip->id == CHIP_PM8606) ?
chip->client : chip->companion;
dev_dbg(chip->dev, "%s(B): client=0x%x\n", __func__, client);
dev_dbg(chip->dev, "%s(B): vote=0x%x status=%d\n",
__func__, chip->osc_vote,
chip->osc_status);
mutex_lock(&chip->osc_lock);
/* Update voting status */
chip->osc_vote |= client;
/* If reference group is off - turn on*/
if (chip->osc_status != PM8606_REF_GP_OSC_ON) {
chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN;
/* Enable Reference group Vsys */
if (pm860x_set_bits(i2c, PM8606_VSYS,
PM8606_VSYS_EN, PM8606_VSYS_EN))
goto out;
/*Enable Internal Oscillator */
if (pm860x_set_bits(i2c, PM8606_MISC,
PM8606_MISC_OSC_EN, PM8606_MISC_OSC_EN))
goto out;
/* Update status (only if writes succeed) */
chip->osc_status = PM8606_REF_GP_OSC_ON;
}
mutex_unlock(&chip->osc_lock);
dev_dbg(chip->dev, "%s(A): vote=0x%x status=%d ret=%d\n",
__func__, chip->osc_vote,
chip->osc_status, ret);
return 0;
out:
mutex_unlock(&chip->osc_lock);
return ret;
}
EXPORT_SYMBOL(pm8606_osc_enable);
int pm8606_osc_disable(struct pm860x_chip *chip, unsigned short client)
{
int ret = -EIO;
struct i2c_client *i2c = (chip->id == CHIP_PM8606) ?
chip->client : chip->companion;
dev_dbg(chip->dev, "%s(B): client=0x%x\n", __func__, client);
dev_dbg(chip->dev, "%s(B): vote=0x%x status=%d\n",
__func__, chip->osc_vote,
chip->osc_status);
mutex_lock(&chip->osc_lock);
/*Update voting status */
chip->osc_vote &= ~(client);
/* If reference group is off and this is the last client to release
* - turn off */
if ((chip->osc_status != PM8606_REF_GP_OSC_OFF) &&
(chip->osc_vote == REF_GP_NO_CLIENTS)) {
chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN;
/* Disable Reference group Vsys */
if (pm860x_set_bits(i2c, PM8606_VSYS, PM8606_VSYS_EN, 0))
goto out;
/* Disable Internal Oscillator */
if (pm860x_set_bits(i2c, PM8606_MISC, PM8606_MISC_OSC_EN, 0))
goto out;
chip->osc_status = PM8606_REF_GP_OSC_OFF;
}
mutex_unlock(&chip->osc_lock);
dev_dbg(chip->dev, "%s(A): vote=0x%x status=%d ret=%d\n",
__func__, chip->osc_vote,
chip->osc_status, ret);
return 0;
out:
mutex_unlock(&chip->osc_lock);
return ret;
}
EXPORT_SYMBOL(pm8606_osc_disable);
static void __devinit device_osc_init(struct i2c_client *i2c)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
mutex_init(&chip->osc_lock);
/* init portofino reference group voting and status */
/* Disable Reference group Vsys */
pm860x_set_bits(i2c, PM8606_VSYS, PM8606_VSYS_EN, 0);
/* Disable Internal Oscillator */
pm860x_set_bits(i2c, PM8606_MISC, PM8606_MISC_OSC_EN, 0);
chip->osc_vote = REF_GP_NO_CLIENTS;
chip->osc_status = PM8606_REF_GP_OSC_OFF;
}
static void __devinit device_bk_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
......@@ -767,6 +862,15 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
return;
}
static void __devinit device_8606_init(struct pm860x_chip *chip,
struct i2c_client *i2c,
struct pm860x_platform_data *pdata)
{
device_osc_init(i2c);
device_bk_init(chip, pdata);
device_led_init(chip, pdata);
}
int __devinit pm860x_device_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
......@@ -774,8 +878,7 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
switch (chip->id) {
case CHIP_PM8606:
device_bk_init(chip, pdata);
device_led_init(chip, pdata);
device_8606_init(chip, chip->client, pdata);
break;
case CHIP_PM8607:
device_8607_init(chip, chip->client, pdata);
......@@ -785,8 +888,7 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
if (chip->companion) {
switch (chip->id) {
case CHIP_PM8607:
device_bk_init(chip, pdata);
device_led_init(chip, pdata);
device_8606_init(chip, chip->companion, pdata);
break;
case CHIP_PM8606:
device_8607_init(chip, chip->companion, pdata);
......
......@@ -334,10 +334,35 @@ static int __devexit pm860x_remove(struct i2c_client *client)
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int pm860x_suspend(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct pm860x_chip *chip = i2c_get_clientdata(client);
if (device_may_wakeup(dev) && chip->wakeup_flag)
enable_irq_wake(chip->core_irq);
return 0;
}
static int pm860x_resume(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct pm860x_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(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
static struct i2c_driver pm860x_driver = {
.driver = {
.name = "88PM860x",
.owner = THIS_MODULE,
.pm = &pm860x_pm_ops,
},
.probe = pm860x_probe,
.remove = __devexit_p(pm860x_remove),
......
......@@ -143,6 +143,21 @@ config TPS6507X
This driver can also be built as a module. If so, the module
will be called tps6507x.
config MFD_TPS65217
tristate "TPS65217 Power Management / White LED chips"
depends on I2C
select MFD_CORE
select REGMAP_I2C
help
If you say yes here you get support for the TPS65217 series of
Power Management / White LED chips.
These include voltage regulators, lithium ion/polymer battery
charger, wled and other features that are often used in portable
devices.
This driver can also be built as a module. If so, the module
will be called tps65217.
config MFD_TPS6586X
bool "TPS6586x Power Management chips"
depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
......@@ -162,6 +177,7 @@ config MFD_TPS65910
depends on I2C=y && GPIOLIB
select MFD_CORE
select GPIO_TPS65910
select REGMAP_I2C
help
if you say yes here you get support for the TPS65910 series of
Power Management chips.
......@@ -171,7 +187,7 @@ config MFD_TPS65912
depends on GPIOLIB
config MFD_TPS65912_I2C
bool "TPS95612 Power Management chip with I2C"
bool "TPS65912 Power Management chip with I2C"
select MFD_CORE
select MFD_TPS65912
depends on I2C=y && GPIOLIB
......@@ -400,7 +416,7 @@ config MFD_MAX8997
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
help
Say yes here to support for Maxim Semiconductor MAX8998/8966.
Say yes here to support for Maxim Semiconductor MAX8997/8966.
This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
MUIC controls on chip.
This driver provides common support for accessing the device;
......@@ -812,6 +828,18 @@ config MFD_PM8XXX_IRQ
config TPS65911_COMPARATOR
tristate
config MFD_TPS65090
bool "TPS65090 Power Management chips"
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
help
If you say yes here you get support for the TPS65090 series of
Power Management chips.
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the
functionality of the device.
config MFD_AAT2870_CORE
bool "Support for the AnalogicTech AAT2870"
select MFD_CORE
......@@ -831,6 +859,28 @@ config MFD_INTEL_MSIC
Passage) chip. This chip embeds audio, battery, GPIO, etc.
devices used in Intel Medfield platforms.
config MFD_RC5T583
bool "Ricoh RC5T583 Power Management system device"
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
help
Select this option to get support for the RICOH583 Power
Management system device.
This driver provides common support for accessing the device
through i2c interface. The device supports multiple sub-devices
like GPIO, interrupts, RTC, LDO and DCDC regulators, onkey.
Additional drivers must be enabled in order to use the
different functionality of the device.
config MFD_ANATOP
bool "Support for Freescale i.MX on-chip ANATOP controller"
depends on SOC_IMX6Q
help
Select this option to enable Freescale i.MX on-chip ANATOP
MFD controller. This controller embeds regulator and
thermal devices for Freescale i.MX platforms.
endmenu
endif
......
......@@ -38,6 +38,7 @@ obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o
obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o
obj-$(CONFIG_TPS6507X) += tps6507x.o
obj-$(CONFIG_MFD_TPS65217) += tps65217.o
obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o
tps65912-objs := tps65912-core.o tps65912-irq.o
obj-$(CONFIG_MFD_TPS65912) += tps65912.o
......@@ -109,6 +110,9 @@ obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o
obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o
This diff is collapsed.
......@@ -11,7 +11,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/db8500-prcmu.h>
#include <linux/mfd/dbx500-prcmu.h>
static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
{
......@@ -23,6 +23,18 @@ static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
return ret;
}
static int ab8500_i2c_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask,
u8 data)
{
int ret;
ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data,
&mask, 1);
if (ret < 0)
dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
return ret;
}
static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr)
{
int ret;
......@@ -38,6 +50,7 @@ static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr)
static int __devinit ab8500_i2c_probe(struct platform_device *plf)
{
const struct platform_device_id *platid = platform_get_device_id(plf);
struct ab8500 *ab8500;
struct resource *resource;
int ret;
......@@ -58,13 +71,15 @@ static int __devinit ab8500_i2c_probe(struct platform_device *plf)
ab8500->read = ab8500_i2c_read;
ab8500->write = ab8500_i2c_write;
ab8500->write_masked = ab8500_i2c_write_masked;
platform_set_drvdata(plf, ab8500);
ret = ab8500_init(ab8500);
ret = ab8500_init(ab8500, platid->driver_data);
if (ret)
kfree(ab8500);
return ret;
}
......@@ -78,13 +93,22 @@ static int __devexit ab8500_i2c_remove(struct platform_device *plf)
return 0;
}
static const struct platform_device_id ab8500_id[] = {
{ "ab8500-i2c", AB8500_VERSION_AB8500 },
{ "ab8505-i2c", AB8500_VERSION_AB8505 },
{ "ab9540-i2c", AB8500_VERSION_AB9540 },
{ "ab8540-i2c", AB8500_VERSION_AB8540 },
{ }
};
static struct platform_driver ab8500_i2c_driver = {
.driver = {
.name = "ab8500-i2c",
.owner = THIS_MODULE,
},
.probe = ab8500_i2c_probe,
.remove = __devexit_p(ab8500_i2c_remove)
.remove = __devexit_p(ab8500_i2c_remove),
.id_table = ab8500_id,
};
static int __init ab8500_i2c_init(void)
......
/*
* Anatop MFD driver
*
* Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
* Copyright (C) 2012 Linaro
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/mfd/anatop.h>
u32 anatop_get_bits(struct anatop *adata, u32 addr, int bit_shift,
int bit_width)
{
u32 val, mask;
if (bit_width == 32)
mask = ~0;
else
mask = (1 << bit_width) - 1;
val = readl(adata->ioreg + addr);
val = (val >> bit_shift) & mask;
return val;
}
EXPORT_SYMBOL_GPL(anatop_get_bits);
void anatop_set_bits(struct anatop *adata, u32 addr, int bit_shift,
int bit_width, u32 data)
{
u32 val, mask;
if (bit_width == 32)
mask = ~0;
else
mask = (1 << bit_width) - 1;
spin_lock(&adata->reglock);
val = readl(adata->ioreg + addr) & ~(mask << bit_shift);
writel((data << bit_shift) | val, adata->ioreg + addr);
spin_unlock(&adata->reglock);
}
EXPORT_SYMBOL_GPL(anatop_set_bits);
static const struct of_device_id of_anatop_match[] = {
{ .compatible = "fsl,imx6q-anatop", },
{ },
};
static int __devinit of_anatop_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
void *ioreg;
struct anatop *drvdata;
ioreg = of_iomap(np, 0);
if (!ioreg)
return -EADDRNOTAVAIL;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->ioreg = ioreg;
spin_lock_init(&drvdata->reglock);
platform_set_drvdata(pdev, drvdata);
of_platform_populate(np, of_anatop_match, NULL, dev);
return 0;
}
static int __devexit of_anatop_remove(struct platform_device *pdev)
{
struct anatop *drvdata;
drvdata = platform_get_drvdata(pdev);
iounmap(drvdata->ioreg);
return 0;
}
static struct platform_driver anatop_of_driver = {
.driver = {
.name = "anatop-mfd",
.owner = THIS_MODULE,
.of_match_table = of_anatop_match,
},
.probe = of_anatop_probe,
.remove = of_anatop_remove,
};
static int __init anatop_init(void)
{
return platform_driver_register(&anatop_of_driver);
}
postcore_initcall(anatop_init);
static void __exit anatop_exit(void)
{
platform_driver_unregister(&anatop_of_driver);
}
module_exit(anatop_exit);
MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
MODULE_DESCRIPTION("ANATOP MFD driver");
MODULE_LICENSE("GPL v2");
......@@ -525,6 +525,11 @@ static void asic3_gpio_set(struct gpio_chip *chip,
return;
}
static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO;
}
static __init int asic3_gpio_probe(struct platform_device *pdev,
u16 *gpio_config, int num)
{
......@@ -976,6 +981,7 @@ static int __init asic3_probe(struct platform_device *pdev)
asic->gpio.set = asic3_gpio_set;
asic->gpio.direction_input = asic3_gpio_direction_input;
asic->gpio.direction_output = asic3_gpio_direction_output;
asic->gpio.to_irq = asic3_gpio_to_irq;
ret = asic3_gpio_probe(pdev,
pdata->gpio_config,
......
......@@ -16,7 +16,6 @@
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mutex.h>
#include <linux/mfd/core.h>
#include <linux/slab.h>
#include <linux/module.h>
......@@ -647,8 +646,6 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
struct irq_desc *desc;
int ret;
mutex_init(&da9052->io_lock);
if (pdata && pdata->init != NULL)
pdata->init(da9052);
......
......@@ -74,24 +74,27 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client,
ret = da9052_i2c_enable_multiwrite(da9052);
if (ret < 0)
goto err;
goto err_regmap;
ret = da9052_device_init(da9052, id->driver_data);
if (ret != 0)
goto err;
goto err_regmap;
return 0;
err_regmap:
regmap_exit(da9052->regmap);
err:
kfree(da9052);
return ret;
}
static int da9052_i2c_remove(struct i2c_client *client)
static int __devexit da9052_i2c_remove(struct i2c_client *client)
{
struct da9052 *da9052 = i2c_get_clientdata(client);
da9052_device_exit(da9052);
regmap_exit(da9052->regmap);
kfree(da9052);
return 0;
......@@ -107,7 +110,7 @@ static struct i2c_device_id da9052_i2c_id[] = {
static struct i2c_driver da9052_i2c_driver = {
.probe = da9052_i2c_probe,
.remove = da9052_i2c_remove,
.remove = __devexit_p(da9052_i2c_remove),
.id_table = da9052_i2c_id,
.driver = {
.name = "da9052",
......
......@@ -21,7 +21,7 @@
#include <linux/mfd/da9052/da9052.h>
static int da9052_spi_probe(struct spi_device *spi)
static int __devinit da9052_spi_probe(struct spi_device *spi)
{
int ret;
const struct spi_device_id *id = spi_get_device_id(spi);
......@@ -52,20 +52,23 @@ static int da9052_spi_probe(struct spi_device *spi)
ret = da9052_device_init(da9052, id->driver_data);
if (ret != 0)
goto err;
goto err_regmap;
return 0;
err_regmap:
regmap_exit(da9052->regmap);
err:
kfree(da9052);
return ret;
}
static int da9052_spi_remove(struct spi_device *spi)
static int __devexit da9052_spi_remove(struct spi_device *spi)
{
struct da9052 *da9052 = dev_get_drvdata(&spi->dev);
da9052_device_exit(da9052);
regmap_exit(da9052->regmap);
kfree(da9052);
return 0;
......
This diff is collapsed.
......@@ -17,41 +17,41 @@
#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))
#define PRCM_SVACLK_MGT_OFF 0x008
#define PRCM_SIACLK_MGT_OFF 0x00C
#define PRCM_SGACLK_MGT_OFF 0x014
#define PRCM_UARTCLK_MGT_OFF 0x018
#define PRCM_MSP02CLK_MGT_OFF 0x01C
#define PRCM_I2CCLK_MGT_OFF 0x020
#define PRCM_SDMMCCLK_MGT_OFF 0x024
#define PRCM_SLIMCLK_MGT_OFF 0x028
#define PRCM_PER1CLK_MGT_OFF 0x02C
#define PRCM_PER2CLK_MGT_OFF 0x030
#define PRCM_PER3CLK_MGT_OFF 0x034
#define PRCM_PER5CLK_MGT_OFF 0x038
#define PRCM_PER6CLK_MGT_OFF 0x03C
#define PRCM_PER7CLK_MGT_OFF 0x040
#define PRCM_PWMCLK_MGT_OFF 0x044 /* for DB5500 */
#define PRCM_IRDACLK_MGT_OFF 0x048 /* for DB5500 */
#define PRCM_IRRCCLK_MGT_OFF 0x04C /* for DB5500 */
#define PRCM_LCDCLK_MGT_OFF 0x044
#define PRCM_BMLCLK_MGT_OFF 0x04C
#define PRCM_HSITXCLK_MGT_OFF 0x050
#define PRCM_HSIRXCLK_MGT_OFF 0x054
#define PRCM_HDMICLK_MGT_OFF 0x058
#define PRCM_APEATCLK_MGT_OFF 0x05C
#define PRCM_APETRACECLK_MGT_OFF 0x060
#define PRCM_MCDECLK_MGT_OFF 0x064
#define PRCM_IPI2CCLK_MGT_OFF 0x068
#define PRCM_DSIALTCLK_MGT_OFF 0x06C
#define PRCM_DMACLK_MGT_OFF 0x074
#define PRCM_B2R2CLK_MGT_OFF 0x078
#define PRCM_TVCLK_MGT_OFF 0x07C
#define PRCM_UNIPROCLK_MGT_OFF 0x278
#define PRCM_SSPCLK_MGT_OFF 0x280
#define PRCM_RNGCLK_MGT_OFF 0x284
#define PRCM_UICCCLK_MGT_OFF 0x27C
#define PRCM_MSP1CLK_MGT_OFF 0x288
#define PRCM_CLK_MGT(_offset) (void __iomem *)(IO_ADDRESS(U8500_PRCMU_BASE) \
+ _offset)
#define PRCM_ACLK_MGT PRCM_CLK_MGT(0x004)
#define PRCM_SVACLK_MGT PRCM_CLK_MGT(0x008)
#define PRCM_SIACLK_MGT PRCM_CLK_MGT(0x00C)
#define PRCM_SGACLK_MGT PRCM_CLK_MGT(0x014)
#define PRCM_UARTCLK_MGT PRCM_CLK_MGT(0x018)
#define PRCM_MSP02CLK_MGT PRCM_CLK_MGT(0x01C)
#define PRCM_I2CCLK_MGT PRCM_CLK_MGT(0x020)
#define PRCM_SDMMCCLK_MGT PRCM_CLK_MGT(0x024)
#define PRCM_SLIMCLK_MGT PRCM_CLK_MGT(0x028)
#define PRCM_PER1CLK_MGT PRCM_CLK_MGT(0x02C)
#define PRCM_PER2CLK_MGT PRCM_CLK_MGT(0x030)
#define PRCM_PER3CLK_MGT PRCM_CLK_MGT(0x034)
#define PRCM_PER5CLK_MGT PRCM_CLK_MGT(0x038)
#define PRCM_PER6CLK_MGT PRCM_CLK_MGT(0x03C)
#define PRCM_PER7CLK_MGT PRCM_CLK_MGT(0x040)
#define PRCM_LCDCLK_MGT PRCM_CLK_MGT(0x044)
#define PRCM_BMLCLK_MGT PRCM_CLK_MGT(0x04C)
#define PRCM_HSITXCLK_MGT PRCM_CLK_MGT(0x050)
#define PRCM_HSIRXCLK_MGT PRCM_CLK_MGT(0x054)
#define PRCM_HDMICLK_MGT PRCM_CLK_MGT(0x058)
#define PRCM_APEATCLK_MGT PRCM_CLK_MGT(0x05C)
#define PRCM_APETRACECLK_MGT PRCM_CLK_MGT(0x060)
#define PRCM_MCDECLK_MGT PRCM_CLK_MGT(0x064)
#define PRCM_IPI2CCLK_MGT PRCM_CLK_MGT(0x068)
#define PRCM_DSIALTCLK_MGT PRCM_CLK_MGT(0x06C)
#define PRCM_DMACLK_MGT PRCM_CLK_MGT(0x074)
#define PRCM_B2R2CLK_MGT PRCM_CLK_MGT(0x078)
#define PRCM_TVCLK_MGT PRCM_CLK_MGT(0x07C)
#define PRCM_UNIPROCLK_MGT PRCM_CLK_MGT(0x278)
#define PRCM_SSPCLK_MGT PRCM_CLK_MGT(0x280)
#define PRCM_RNGCLK_MGT PRCM_CLK_MGT(0x284)
#define PRCM_UICCCLK_MGT PRCM_CLK_MGT(0x27C)
#define PRCM_MSP1CLK_MGT PRCM_CLK_MGT(0x288)
#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118)
#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f
......@@ -79,6 +79,8 @@
/* ARM WFI Standby signal register */
#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130)
#define PRCM_ARM_WFI_STANDBY_WFI0 0x08
#define PRCM_ARM_WFI_STANDBY_WFI1 0x10
#define PRCM_IOCR (_PRCMU_BASE + 0x310)
#define PRCM_IOCR_IOFORCE 0x1
......@@ -131,20 +133,58 @@
#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420)
#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424)
#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP BIT(11)
#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI BIT(22)
/* PRCMU clock/PLL/reset registers */
#define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080)
#define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084)
#define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C)
#define PRCM_PLL_FREQ_D_SHIFT 0
#define PRCM_PLL_FREQ_D_MASK BITS(0, 7)
#define PRCM_PLL_FREQ_N_SHIFT 8
#define PRCM_PLL_FREQ_N_MASK BITS(8, 13)
#define PRCM_PLL_FREQ_R_SHIFT 16
#define PRCM_PLL_FREQ_R_MASK BITS(16, 18)
#define PRCM_PLL_FREQ_SELDIV2 BIT(24)
#define PRCM_PLL_FREQ_DIV2EN BIT(25)
#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500)
#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504)
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
#define PRCM_LCDCLK_MGT (_PRCMU_BASE + PRCM_LCDCLK_MGT_OFF)
#define PRCM_MCDECLK_MGT (_PRCMU_BASE + PRCM_MCDECLK_MGT_OFF)
#define PRCM_HDMICLK_MGT (_PRCMU_BASE + PRCM_HDMICLK_MGT_OFF)
#define PRCM_TVCLK_MGT (_PRCMU_BASE + PRCM_TVCLK_MGT_OFF)
#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530)
#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C)
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4)
#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8)
#define PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE BIT(0)
#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 BIT(0)
#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3 BIT(1)
#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT 0
#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK BITS(0, 2)
#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT 8
#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK BITS(8, 10)
#define PRCM_DSI_PLLOUT_SEL_OFF 0
#define PRCM_DSI_PLLOUT_SEL_PHI 1
#define PRCM_DSI_PLLOUT_SEL_PHI_2 2
#define PRCM_DSI_PLLOUT_SEL_PHI_4 3
#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT 0
#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK BITS(0, 7)
#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT 8
#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK BITS(8, 15)
#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT 16
#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK BITS(16, 23)
#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN BIT(24)
#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN BIT(25)
#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN BIT(26)
#define PRCM_APE_RESETN_DSIPLL_RESETN BIT(14)
#define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC)
#define PRCM_CLKOCR_CLKOUT0_REF_CLK (1 << 0)
#define PRCM_CLKOCR_CLKOUT0_MASK BITS(0, 13)
......@@ -184,8 +224,14 @@
#define PRCM_CLKOCR_CLK1TYPE BIT(28)
#define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4)
#define PRCM_CLK_MGT_CLKPLLSW_SOC0 BIT(5)
#define PRCM_CLK_MGT_CLKPLLSW_SOC1 BIT(6)
#define PRCM_CLK_MGT_CLKPLLSW_DDR BIT(7)
#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7)
#define PRCM_CLK_MGT_CLKEN BIT(8)
#define PRCM_CLK_MGT_CLK38 BIT(9)
#define PRCM_CLK_MGT_CLK38DIV BIT(11)
#define PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN BIT(12)
/* GPIOCR register */
#define PRCM_GPIOCR_SPI2_SELECT BIT(23)
......
......@@ -560,6 +560,8 @@ EXPORT_SYMBOL(mc13xxx_get_flags);
#define MC13XXX_ADC1_CHAN0_SHIFT 5
#define MC13XXX_ADC1_CHAN1_SHIFT 8
#define MC13783_ADC1_ATO_SHIFT 11
#define MC13783_ADC1_ATOX (1 << 19)
struct mc13xxx_adcdone_data {
struct mc13xxx *mc13xxx;
......@@ -580,7 +582,8 @@ static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
#define MC13XXX_ADC_WORKING (1 << 0)
int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
unsigned int channel, unsigned int *sample)
unsigned int channel, u8 ato, bool atox,
unsigned int *sample)
{
u32 adc0, adc1, old_adc0;
int i, ret;
......@@ -631,6 +634,9 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
return -EINVAL;
}
adc1 |= ato << MC13783_ADC1_ATO_SHIFT;
if (atox)
adc1 |= MC13783_ADC1_ATOX;
dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__);
mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
mc13xxx_handler_adcdone, __func__, &adcdone_data);
......@@ -813,7 +819,8 @@ static int mc13xxx_probe(struct spi_device *spi)
mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN)
mc13xxx_add_subdevice(mc13xxx, "%s-ts");
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts",
&pdata->touch, sizeof(pdata->touch));
if (pdata) {
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
......
......@@ -162,7 +162,7 @@ int mfd_add_devices(struct device *parent, int id,
atomic_t *cnts;
/* initialize reference counting for all cells */
cnts = kcalloc(sizeof(*cnts), n_devs, GFP_KERNEL);
cnts = kcalloc(n_devs, sizeof(*cnts), GFP_KERNEL);
if (!cnts)
return -ENOMEM;
......
......@@ -170,7 +170,7 @@ struct usbhs_hcd_omap {
/*-------------------------------------------------------------------------*/
const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
static u64 usbhs_dmamask = ~(u32)0;
static u64 usbhs_dmamask = DMA_BIT_MASK(32);
/*-------------------------------------------------------------------------*/
......@@ -223,7 +223,7 @@ static struct platform_device *omap_usbhs_alloc_child(const char *name,
}
child->dev.dma_mask = &usbhs_dmamask;
child->dev.coherent_dma_mask = 0xffffffff;
dma_set_coherent_mask(&child->dev, DMA_BIT_MASK(32));
child->dev.parent = dev;
ret = platform_device_add(child);
......@@ -799,14 +799,13 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, omap);
omap_usbhs_init(dev);
ret = omap_usbhs_alloc_children(pdev);
if (ret) {
dev_err(dev, "omap_usbhs_alloc_children failed\n");
goto err_alloc;
}
omap_usbhs_init(dev);
goto end_probe;
err_alloc:
......
......@@ -46,13 +46,7 @@ EXPORT_SYMBOL_GPL(pcf50633_read_block);
int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
int nr_regs, u8 *data)
{
int ret;
ret = regmap_raw_write(pcf->regmap, reg, data, nr_regs);
if (ret != 0)
return ret;
return nr_regs;
return regmap_raw_write(pcf->regmap, reg, data, nr_regs);
}
EXPORT_SYMBOL_GPL(pcf50633_write_block);
......
......@@ -19,32 +19,7 @@
#include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/gpio.h>
enum pcf50633_regulator_id {
PCF50633_REGULATOR_AUTO,
PCF50633_REGULATOR_DOWN1,
PCF50633_REGULATOR_DOWN2,
PCF50633_REGULATOR_LDO1,
PCF50633_REGULATOR_LDO2,
PCF50633_REGULATOR_LDO3,
PCF50633_REGULATOR_LDO4,
PCF50633_REGULATOR_LDO5,
PCF50633_REGULATOR_LDO6,
PCF50633_REGULATOR_HCLDO,
PCF50633_REGULATOR_MEMLDO,
};
#define PCF50633_REG_AUTOOUT 0x1a
#define PCF50633_REG_DOWN1OUT 0x1e
#define PCF50633_REG_DOWN2OUT 0x22
#define PCF50633_REG_MEMLDOOUT 0x26
#define PCF50633_REG_LDO1OUT 0x2d
#define PCF50633_REG_LDO2OUT 0x2f
#define PCF50633_REG_LDO3OUT 0x31
#define PCF50633_REG_LDO4OUT 0x33
#define PCF50633_REG_LDO5OUT 0x35
#define PCF50633_REG_LDO6OUT 0x37
#define PCF50633_REG_HCLDOOUT 0x39
#include <linux/mfd/pcf50633/pmic.h>
static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
[PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT,
......
......@@ -19,12 +19,7 @@
#include <linux/slab.h>
#include <linux/mfd/pcf50633/core.h>
/* Two MBCS registers used during cold start */
#define PCF50633_REG_MBCS1 0x4b
#define PCF50633_REG_MBCS2 0x4c
#define PCF50633_MBCS1_USBPRES 0x01
#define PCF50633_MBCS1_ADAPTPRES 0x01
#include <linux/mfd/pcf50633/mbc.h>
int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
void (*handler) (int, void *), void *data)
......
This diff is collapsed.
This diff is collapsed.
......@@ -26,7 +26,27 @@
#include <linux/mfd/s5m87xx/s5m-rtc.h>
#include <linux/regmap.h>
static struct mfd_cell s5m87xx_devs[] = {
static struct mfd_cell s5m8751_devs[] = {
{
.name = "s5m8751-pmic",
}, {
.name = "s5m-charger",
}, {
.name = "s5m8751-codec",
},
};
static struct mfd_cell s5m8763_devs[] = {
{
.name = "s5m8763-pmic",
}, {
.name = "s5m-rtc",
}, {
.name = "s5m-charger",
},
};
static struct mfd_cell s5m8767_devs[] = {
{
.name = "s5m8767-pmic",
}, {
......@@ -42,7 +62,7 @@ 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);;
return regmap_bulk_read(s5m87xx->regmap, reg, buf, count);
}
EXPORT_SYMBOL_GPL(s5m_bulk_read);
......@@ -54,7 +74,7 @@ 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));
return regmap_raw_write(s5m87xx->regmap, reg, buf, count);
}
EXPORT_SYMBOL_GPL(s5m_bulk_write);
......@@ -74,10 +94,10 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c,
{
struct s5m_platform_data *pdata = i2c->dev.platform_data;
struct s5m87xx_dev *s5m87xx;
int ret = 0;
int error;
int ret;
s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL);
s5m87xx = devm_kzalloc(&i2c->dev, sizeof(struct s5m87xx_dev),
GFP_KERNEL);
if (s5m87xx == NULL)
return -ENOMEM;
......@@ -96,9 +116,9 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c,
s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config);
if (IS_ERR(s5m87xx->regmap)) {
error = PTR_ERR(s5m87xx->regmap);
ret = PTR_ERR(s5m87xx->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
error);
ret);
goto err;
}
......@@ -112,9 +132,23 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c,
pm_runtime_set_active(s5m87xx->dev);
ret = mfd_add_devices(s5m87xx->dev, -1,
s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs),
NULL, 0);
switch (s5m87xx->device_type) {
case S5M8751X:
ret = mfd_add_devices(s5m87xx->dev, -1, s5m8751_devs,
ARRAY_SIZE(s5m8751_devs), NULL, 0);
break;
case S5M8763X:
ret = mfd_add_devices(s5m87xx->dev, -1, s5m8763_devs,
ARRAY_SIZE(s5m8763_devs), NULL, 0);
break;
case S5M8767X:
ret = mfd_add_devices(s5m87xx->dev, -1, s5m8767_devs,
ARRAY_SIZE(s5m8767_devs), NULL, 0);
break;
default:
/* If this happens the probe function is problem */
BUG();
}
if (ret < 0)
goto err;
......@@ -126,7 +160,6 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c,
s5m_irq_exit(s5m87xx);
i2c_unregister_device(s5m87xx->rtc);
regmap_exit(s5m87xx->regmap);
kfree(s5m87xx);
return ret;
}
......@@ -138,7 +171,6 @@ static int s5m87xx_i2c_remove(struct i2c_client *i2c)
s5m_irq_exit(s5m87xx);
i2c_unregister_device(s5m87xx->rtc);
regmap_exit(s5m87xx->regmap);
kfree(s5m87xx);
return 0;
}
......
......@@ -342,7 +342,10 @@ int s5m_irq_resume(struct s5m87xx_dev *s5m87xx)
s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx);
break;
default:
break;
dev_err(s5m87xx->dev,
"Unknown device type %d\n",
s5m87xx->device_type);
return -EINVAL;
}
}
......@@ -444,7 +447,9 @@ int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
}
break;
default:
break;
dev_err(s5m87xx->dev,
"Unknown device type %d\n", s5m87xx->device_type);
return -EINVAL;
}
if (!s5m87xx->ono)
......@@ -467,12 +472,15 @@ int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
IRQF_ONESHOT, "s5m87xx-ono", s5m87xx);
break;
default:
ret = -EINVAL;
break;
}
if (ret)
if (ret) {
dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
s5m87xx->ono, ret);
return ret;
}
return 0;
}
......
......@@ -387,14 +387,6 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
EXPORT_SYMBOL_GPL(sm501_unit_power);
/* Perform a rounded division. */
static long sm501fb_round_div(long num, long denom)
{
/* n / d + 1 / 2 = (2n + d) / 2d */
return (2 * num + denom) / (2 * denom);
}
/* clock value structure. */
struct sm501_clock {
unsigned long mclk;
......@@ -428,7 +420,7 @@ static int sm501_calc_clock(unsigned long freq,
/* try all 8 shift values.*/
for (shift = 0; shift < 8; shift++) {
/* Calculate difference to requested clock */
diff = sm501fb_round_div(mclk, divider << shift) - freq;
diff = DIV_ROUND_CLOSEST(mclk, divider << shift) - freq;
if (diff < 0)
diff = -diff;
......
......@@ -298,6 +298,11 @@ static struct mfd_cell stmpe_gpio_cell = {
.num_resources = ARRAY_SIZE(stmpe_gpio_resources),
};
static struct mfd_cell stmpe_gpio_cell_noirq = {
.name = "stmpe-gpio",
/* gpio cell resources consist of an irq only so no resources here */
};
/*
* Keypad (1601, 2401, 2403)
*/
......@@ -346,6 +351,13 @@ static struct stmpe_variant_block stmpe801_blocks[] = {
},
};
static struct stmpe_variant_block stmpe801_blocks_noirq[] = {
{
.cell = &stmpe_gpio_cell_noirq,
.block = STMPE_BLOCK_GPIO,
},
};
static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
bool enable)
{
......@@ -367,6 +379,17 @@ static struct stmpe_variant_info stmpe801 = {
.enable = stmpe801_enable,
};
static struct stmpe_variant_info stmpe801_noirq = {
.name = "stmpe801",
.id_val = STMPE801_ID,
.id_mask = 0xffff,
.num_gpios = 8,
.regs = stmpe801_regs,
.blocks = stmpe801_blocks_noirq,
.num_blocks = ARRAY_SIZE(stmpe801_blocks_noirq),
.enable = stmpe801_enable,
};
/*
* Touchscreen (STMPE811 or STMPE610)
*/
......@@ -712,7 +735,7 @@ static struct stmpe_variant_info stmpe2403 = {
.enable_autosleep = stmpe1601_autosleep, /* same as stmpe1601 */
};
static struct stmpe_variant_info *stmpe_variant_info[] = {
static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
[STMPE610] = &stmpe610,
[STMPE801] = &stmpe801,
[STMPE811] = &stmpe811,
......@@ -721,6 +744,16 @@ static struct stmpe_variant_info *stmpe_variant_info[] = {
[STMPE2403] = &stmpe2403,
};
/*
* These devices can be connected in a 'no-irq' configuration - the irq pin
* is not used and the device cannot interrupt the CPU. Here we only list
* devices which support this configuration - the driver will fail probing
* for any devices not listed here which are configured in this way.
*/
static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = {
[STMPE801] = &stmpe801_noirq,
};
static irqreturn_t stmpe_irq(int irq, void *data)
{
struct stmpe *stmpe = data;
......@@ -864,7 +897,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;
u8 icr = 0;
unsigned int id;
u8 data[2];
int ret;
......@@ -887,6 +920,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
if (ret)
return ret;
if (stmpe->irq >= 0) {
if (id == STMPE801_ID)
icr = STMPE801_REG_SYS_CTRL_INT_EN;
else
......@@ -913,6 +947,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
else
icr ^= STMPE_ICR_LSB_HIGH;
}
}
if (stmpe->pdata->autosleep) {
ret = stmpe_autosleep(stmpe, autosleep_timeout);
......@@ -1001,20 +1036,39 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
stmpe->irq = ci->irq;
}
if (stmpe->irq < 0) {
/* use alternate variant info for no-irq mode, if supported */
dev_info(stmpe->dev,
"%s configured in no-irq mode by platform data\n",
stmpe->variant->name);
if (!stmpe_noirq_variant_info[stmpe->partnum]) {
dev_err(stmpe->dev,
"%s does not support no-irq mode!\n",
stmpe->variant->name);
ret = -ENODEV;
goto free_gpio;
}
stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
}
ret = stmpe_chip_init(stmpe);
if (ret)
goto free_gpio;
if (stmpe->irq >= 0) {
ret = stmpe_irq_init(stmpe);
if (ret)
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);
dev_err(stmpe->dev, "failed to request IRQ: %d\n",
ret);
goto out_removeirq;
}
}
ret = stmpe_devices_init(stmpe);
if (ret) {
......@@ -1026,8 +1080,10 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
out_removedevs:
mfd_remove_devices(stmpe->dev);
if (stmpe->irq >= 0)
free_irq(stmpe->irq, stmpe);
out_removeirq:
if (stmpe->irq >= 0)
stmpe_irq_remove(stmpe);
free_gpio:
if (pdata->irq_over_gpio)
......@@ -1041,8 +1097,10 @@ int stmpe_remove(struct stmpe *stmpe)
{
mfd_remove_devices(stmpe->dev);
if (stmpe->irq >= 0) {
free_irq(stmpe->irq, stmpe);
stmpe_irq_remove(stmpe);
}
if (stmpe->pdata->irq_over_gpio)
gpio_free(stmpe->pdata->irq_gpio);
......@@ -1057,7 +1115,7 @@ static int stmpe_suspend(struct device *dev)
{
struct stmpe *stmpe = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
if (stmpe->irq >= 0 && device_may_wakeup(dev))
enable_irq_wake(stmpe->irq);
return 0;
......@@ -1067,7 +1125,7 @@ static int stmpe_resume(struct device *dev)
{
struct stmpe *stmpe = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
if (stmpe->irq >= 0 && device_may_wakeup(dev))
disable_irq_wake(stmpe->irq);
return 0;
......
This diff is collapsed.
/*
* tps65217.c
*
* TPS65217 chip family multi-function driver
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.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 version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/err.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps65217.h>
/**
* tps65217_reg_read: Read a single tps65217 register.
*
* @tps: Device to read from.
* @reg: Register to read.
* @val: Contians the value
*/
int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,
unsigned int *val)
{
return regmap_read(tps->regmap, reg, val);
}
EXPORT_SYMBOL_GPL(tps65217_reg_read);
/**
* tps65217_reg_write: Write a single tps65217 register.
*
* @tps65217: Device to write to.
* @reg: Register to write to.
* @val: Value to write.
* @level: Password protected level
*/
int tps65217_reg_write(struct tps65217 *tps, unsigned int reg,
unsigned int val, unsigned int level)
{
int ret;
unsigned int xor_reg_val;
switch (level) {
case TPS65217_PROTECT_NONE:
return regmap_write(tps->regmap, reg, val);
case TPS65217_PROTECT_L1:
xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
xor_reg_val);
if (ret < 0)
return ret;
return regmap_write(tps->regmap, reg, val);
case TPS65217_PROTECT_L2:
xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
xor_reg_val);
if (ret < 0)
return ret;
ret = regmap_write(tps->regmap, reg, val);
if (ret < 0)
return ret;
ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
xor_reg_val);
if (ret < 0)
return ret;
return regmap_write(tps->regmap, reg, val);
default:
return -EINVAL;
}
}
EXPORT_SYMBOL_GPL(tps65217_reg_write);
/**
* tps65217_update_bits: Modify bits w.r.t mask, val and level.
*
* @tps65217: Device to write to.
* @reg: Register to read-write to.
* @mask: Mask.
* @val: Value to write.
* @level: Password protected level
*/
int tps65217_update_bits(struct tps65217 *tps, unsigned int reg,
unsigned int mask, unsigned int val, unsigned int level)
{
int ret;
unsigned int data;
ret = tps65217_reg_read(tps, reg, &data);
if (ret) {
dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
return ret;
}
data &= ~mask;
data |= val & mask;
ret = tps65217_reg_write(tps, reg, data, level);
if (ret)
dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
return ret;
}
int tps65217_set_bits(struct tps65217 *tps, unsigned int reg,
unsigned int mask, unsigned int val, unsigned int level)
{
return tps65217_update_bits(tps, reg, mask, val, level);
}
EXPORT_SYMBOL_GPL(tps65217_set_bits);
int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
unsigned int mask, unsigned int level)
{
return tps65217_update_bits(tps, reg, mask, 0, level);
}
EXPORT_SYMBOL_GPL(tps65217_clear_bits);
static struct regmap_config tps65217_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int __devinit tps65217_probe(struct i2c_client *client,
const struct i2c_device_id *ids)
{
struct tps65217 *tps;
struct tps65217_board *pdata = client->dev.platform_data;
int i, ret;
unsigned int version;
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
tps->pdata = pdata;
tps->regmap = regmap_init_i2c(client, &tps65217_regmap_config);
if (IS_ERR(tps->regmap)) {
ret = PTR_ERR(tps->regmap);
dev_err(tps->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
i2c_set_clientdata(client, tps);
tps->dev = &client->dev;
ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);
if (ret < 0) {
dev_err(tps->dev, "Failed to read revision"
" register: %d\n", ret);
goto err_regmap;
}
dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n",
(version & TPS65217_CHIPID_CHIP_MASK) >> 4,
version & TPS65217_CHIPID_REV_MASK);
for (i = 0; i < TPS65217_NUM_REGULATOR; i++) {
struct platform_device *pdev;
pdev = platform_device_alloc("tps65217-pmic", i);
if (!pdev) {
dev_err(tps->dev, "Cannot create regulator %d\n", i);
continue;
}
pdev->dev.parent = tps->dev;
platform_device_add_data(pdev, &pdata->tps65217_init_data[i],
sizeof(pdata->tps65217_init_data[i]));
tps->regulator_pdev[i] = pdev;
platform_device_add(pdev);
}
return 0;
err_regmap:
regmap_exit(tps->regmap);
return ret;
}
static int __devexit tps65217_remove(struct i2c_client *client)
{
struct tps65217 *tps = i2c_get_clientdata(client);
int i;
for (i = 0; i < TPS65217_NUM_REGULATOR; i++)
platform_device_unregister(tps->regulator_pdev[i]);
regmap_exit(tps->regmap);
return 0;
}
static const struct i2c_device_id tps65217_id_table[] = {
{"tps65217", 0xF0},
{/* end of list */}
};
MODULE_DEVICE_TABLE(i2c, tps65217_id_table);
static struct i2c_driver tps65217_driver = {
.driver = {
.name = "tps65217",
},
.id_table = tps65217_id_table,
.probe = tps65217_probe,
.remove = __devexit_p(tps65217_remove),
};
static int __init tps65217_init(void)
{
return i2c_add_driver(&tps65217_driver);
}
subsys_initcall(tps65217_init);
static void __exit tps65217_exit(void)
{
i2c_del_driver(&tps65217_driver);
}
module_exit(tps65217_exit);
MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");
MODULE_DESCRIPTION("TPS65217 chip family multi-function driver");
MODULE_LICENSE("GPL v2");
......@@ -145,12 +145,23 @@ static void tps65910_irq_disable(struct irq_data *data)
tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq));
}
#ifdef CONFIG_PM_SLEEP
static int tps65910_irq_set_wake(struct irq_data *data, unsigned int enable)
{
struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
return irq_set_irq_wake(tps65910->chip_irq, enable);
}
#else
#define tps65910_irq_set_wake NULL
#endif
static struct irq_chip tps65910_irq_chip = {
.name = "tps65910",
.irq_bus_lock = tps65910_irq_lock,
.irq_bus_sync_unlock = tps65910_irq_sync_unlock,
.irq_disable = tps65910_irq_disable,
.irq_enable = tps65910_irq_enable,
.irq_set_wake = tps65910_irq_set_wake,
};
int tps65910_irq_init(struct tps65910 *tps65910, int irq,
......
This diff is collapsed.
This diff is collapsed.
#ifndef __TWL_CORE_H__
#define __TWL_CORE_H__
extern int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
extern int twl6030_init_irq(struct device *dev, int irq_num);
extern int twl6030_exit_irq(void);
extern int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
extern int twl4030_init_irq(struct device *dev, int irq_num);
extern int twl4030_exit_irq(void);
extern int twl4030_init_chip_irq(const char *chip);
......
This diff is collapsed.
This diff is collapsed.
......@@ -89,7 +89,7 @@ static const struct spi_device_id wm831x_spi_ids[] = {
{ "wm8326", WM8326 },
{ },
};
MODULE_DEVICE_TABLE(spi, wm831x_spi_id);
MODULE_DEVICE_TABLE(spi, wm831x_spi_ids);
static struct spi_driver wm831x_spi_driver = {
.driver = {
......
......@@ -271,8 +271,7 @@ static int wm8400_init(struct wm8400 *wm8400,
return -EIO;
}
if (i != reg_data[WM8400_RESET_ID].default_val) {
dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n",
reg);
dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n", i);
return -ENODEV;
}
......
......@@ -639,7 +639,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
}
pm_runtime_enable(wm8994->dev);
pm_runtime_resume(wm8994->dev);
pm_runtime_idle(wm8994->dev);
return 0;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -761,7 +761,7 @@ struct twl_regulator_driver_data {
/*----------------------------------------------------------------------*/
int twl4030_sih_setup(int module);
int twl4030_sih_setup(struct device *dev, int module, int irq_base);
/* Offsets to Power Registers */
#define TWL4030_VDAC_DEV_GRP 0x3B
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -76,8 +76,6 @@ enum da9052_chip_id {
struct da9052_pdata;
struct da9052 {
struct mutex io_lock;
struct device *dev;
struct regmap *regmap;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment