提交 9f24ff6f 编写于 作者: L Linus Torvalds

Merge tag 'mfd-for-linus-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6

Pull MFD fixes from Samuel Ortiz:
 "We have 3 build fixes, a OMAP USB host PHY reset fix and the twl6040
  conversion to an i2c driver.  The latter may not sound like a fix but
  the twl6040 MFD driver won't probe without it, triggering an OMAP4
  audio regression."

* tag 'mfd-for-linus-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6:
  mfd: Fix modular builds of rc5t583 regulator support
  mfd: Fix asic3_gpio_to_irq
  ARM: OMAP3: USB: Fix the EHCI ULPI PHY reset issue
  mfd: Convert twl6040 to i2c driver, and separate it from twl core
  mfd : Fix dbx500 compilation error
......@@ -20,6 +20,7 @@
#include <linux/usb/otg.h>
#include <linux/spi/spi.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/twl6040.h>
#include <linux/gpio_keys.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
......@@ -560,7 +561,7 @@ static struct regulator_init_data sdp4430_vusim = {
},
};
static struct twl4030_codec_data twl6040_codec = {
static struct twl6040_codec_data twl6040_codec = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
.hs_right_step = 0x0f,
......@@ -568,7 +569,7 @@ static struct twl4030_codec_data twl6040_codec = {
.hf_right_step = 0x1d,
};
static struct twl4030_vibra_data twl6040_vibra = {
static struct twl6040_vibra_data twl6040_vibra = {
.vibldrv_res = 8,
.vibrdrv_res = 3,
.viblmotor_res = 10,
......@@ -577,16 +578,14 @@ static struct twl4030_vibra_data twl6040_vibra = {
.vddvibr_uV = 0, /* fixed volt supply - VBAT */
};
static struct twl4030_audio_data twl6040_audio = {
static struct twl6040_platform_data twl6040_data = {
.codec = &twl6040_codec,
.vibra = &twl6040_vibra,
.audpwron_gpio = 127,
.naudint_irq = OMAP44XX_IRQ_SYS_2N,
.irq_base = TWL6040_CODEC_IRQ_BASE,
};
static struct twl4030_platform_data sdp4430_twldata = {
.audio = &twl6040_audio,
/* Regulators */
.vusim = &sdp4430_vusim,
.vaux1 = &sdp4430_vaux1,
......@@ -617,7 +616,8 @@ static int __init omap4_i2c_init(void)
TWL_COMMON_REGULATOR_VCXIO |
TWL_COMMON_REGULATOR_VUSB |
TWL_COMMON_REGULATOR_CLK32KG);
omap4_pmic_init("twl6030", &sdp4430_twldata);
omap4_pmic_init("twl6030", &sdp4430_twldata,
&twl6040_data, OMAP44XX_IRQ_SYS_2N);
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
......
......@@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = {
static void __init omap4_i2c_init(void)
{
omap4_pmic_init("twl6030", &sdp4430_twldata);
omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0);
}
static void __init omap4_init(void)
......
......@@ -25,6 +25,7 @@
#include <linux/gpio.h>
#include <linux/usb/otg.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/twl6040.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
#include <linux/wl12xx.h>
......@@ -284,7 +285,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
return 0;
}
static struct twl4030_codec_data twl6040_codec = {
static struct twl6040_codec_data twl6040_codec = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
.hs_right_step = 0x0f,
......@@ -292,17 +293,14 @@ static struct twl4030_codec_data twl6040_codec = {
.hf_right_step = 0x1d,
};
static struct twl4030_audio_data twl6040_audio = {
static struct twl6040_platform_data twl6040_data = {
.codec = &twl6040_codec,
.audpwron_gpio = 127,
.naudint_irq = OMAP44XX_IRQ_SYS_2N,
.irq_base = TWL6040_CODEC_IRQ_BASE,
};
/* Panda board uses the common PMIC configuration */
static struct twl4030_platform_data omap4_panda_twldata = {
.audio = &twl6040_audio,
};
static struct twl4030_platform_data omap4_panda_twldata;
/*
* Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
......@@ -326,7 +324,8 @@ static int __init omap4_panda_i2c_init(void)
TWL_COMMON_REGULATOR_VCXIO |
TWL_COMMON_REGULATOR_VUSB |
TWL_COMMON_REGULATOR_CLK32KG);
omap4_pmic_init("twl6030", &omap4_panda_twldata);
omap4_pmic_init("twl6030", &omap4_panda_twldata,
&twl6040_data, OMAP44XX_IRQ_SYS_2N);
omap_register_i2c_bus(2, 400, NULL, 0);
/*
* Bus 3 is attached to the DVI port where devices like the pico DLP
......
......@@ -37,6 +37,16 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = {
.flags = I2C_CLIENT_WAKE,
};
static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
{
.addr = 0x48,
.flags = I2C_CLIENT_WAKE,
},
{
I2C_BOARD_INFO("twl6040", 0x4b),
},
};
void __init omap_pmic_init(int bus, u32 clkrate,
const char *pmic_type, int pmic_irq,
struct twl4030_platform_data *pmic_data)
......@@ -49,14 +59,31 @@ void __init omap_pmic_init(int bus, u32 clkrate,
omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
}
void __init omap4_pmic_init(const char *pmic_type,
struct twl4030_platform_data *pmic_data,
struct twl6040_platform_data *twl6040_data, int twl6040_irq)
{
/* PMIC part*/
strncpy(omap4_i2c1_board_info[0].type, pmic_type,
sizeof(omap4_i2c1_board_info[0].type));
omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N;
omap4_i2c1_board_info[0].platform_data = pmic_data;
/* TWL6040 audio IC part */
omap4_i2c1_board_info[1].irq = twl6040_irq;
omap4_i2c1_board_info[1].platform_data = twl6040_data;
omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2);
}
void __init omap_pmic_late_init(void)
{
/* Init the OMAP TWL parameters (if PMIC has been registerd) */
if (!pmic_i2c_board_info.irq)
return;
omap3_twl_init();
omap4_twl_init();
if (pmic_i2c_board_info.irq)
omap3_twl_init();
if (omap4_i2c1_board_info[0].irq)
omap4_twl_init();
}
#if defined(CONFIG_ARCH_OMAP3)
......
......@@ -29,6 +29,7 @@
struct twl4030_platform_data;
struct twl6040_platform_data;
void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
struct twl4030_platform_data *pmic_data);
......@@ -46,12 +47,9 @@ static inline void omap3_pmic_init(const char *pmic_type,
omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);
}
static inline void omap4_pmic_init(const char *pmic_type,
struct twl4030_platform_data *pmic_data)
{
/* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */
omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data);
}
void omap4_pmic_init(const char *pmic_type,
struct twl4030_platform_data *pmic_data,
struct twl6040_platform_data *audio_data, int twl6040_irq);
void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags);
......
......@@ -380,8 +380,7 @@ config INPUT_TWL4030_VIBRA
config INPUT_TWL6040_VIBRA
tristate "Support for TWL6040 Vibrator"
depends on TWL4030_CORE
select TWL6040_CORE
depends on TWL6040_CORE
select INPUT_FF_MEMLESS
help
This option enables support for TWL6040 Vibrator Driver.
......
......@@ -28,7 +28,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/i2c/twl.h>
#include <linux/input.h>
#include <linux/mfd/twl6040.h>
#include <linux/slab.h>
#include <linux/delay.h>
......@@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);
static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
{
struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
struct twl6040_vibra_data *pdata = pdev->dev.platform_data;
struct vibra_info *info;
int ret;
......
......@@ -268,10 +268,17 @@ config TWL6030_PWM
This is used to control charging LED brightness.
config TWL6040_CORE
bool
depends on TWL4030_CORE && GENERIC_HARDIRQS
bool "Support for TWL6040 audio codec"
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
default n
help
Say yes here if you want support for Texas Instruments TWL6040 audio
codec.
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the
functionality of the device (audio, vibra).
config MFD_STMPE
bool "Support STMicroelectronics STMPE"
......
......@@ -527,7 +527,9 @@ static void asic3_gpio_set(struct gpio_chip *chip,
static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO;
struct asic3 *asic = container_of(chip, struct asic3, gpio);
return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO;
}
static __init int asic3_gpio_probe(struct platform_device *pdev,
......
......@@ -25,7 +25,6 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
#include <linux/gpio.h>
#include <plat/usb.h>
#include <linux/pm_runtime.h>
......@@ -502,19 +501,6 @@ static void omap_usbhs_init(struct device *dev)
pm_runtime_get_sync(dev);
spin_lock_irqsave(&omap->lock, flags);
if (pdata->ehci_data->phy_reset) {
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
/* Hold the PHY in RESET for enough time till DIR is high */
udelay(10);
}
omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
......@@ -593,39 +579,10 @@ static void omap_usbhs_init(struct device *dev)
usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
}
if (pdata->ehci_data->phy_reset) {
/* Hold the PHY in RESET for enough time till
* PHY is settled and ready
*/
udelay(10);
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
gpio_set_value
(pdata->ehci_data->reset_gpio_port[0], 1);
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
gpio_set_value
(pdata->ehci_data->reset_gpio_port[1], 1);
}
spin_unlock_irqrestore(&omap->lock, flags);
pm_runtime_put_sync(dev);
}
static void omap_usbhs_deinit(struct device *dev)
{
struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
struct usbhs_omap_platform_data *pdata = &omap->platdata;
if (pdata->ehci_data->phy_reset) {
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
gpio_free(pdata->ehci_data->reset_gpio_port[0]);
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
gpio_free(pdata->ehci_data->reset_gpio_port[1]);
}
}
/**
* usbhs_omap_probe - initialize TI-based HCDs
......@@ -860,7 +817,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
{
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
omap_usbhs_deinit(&pdev->dev);
iounmap(omap->tll_base);
iounmap(omap->uhh_base);
clk_put(omap->init_60m_fclk);
......
......@@ -80,44 +80,6 @@ static struct mfd_cell rc5t583_subdevs[] = {
{.name = "rc5t583-key", }
};
int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_write(rc5t583->regmap, reg, val);
}
int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
unsigned int ival;
int ret;
ret = regmap_read(rc5t583->regmap, reg, &ival);
if (!ret)
*val = (uint8_t)ival;
return ret;
}
int rc5t583_set_bits(struct device *dev, unsigned int reg,
unsigned int bit_mask)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
}
int rc5t583_clear_bits(struct device *dev, unsigned int reg,
unsigned int bit_mask)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
}
int rc5t583_update(struct device *dev, unsigned int reg,
unsigned int val, unsigned int mask)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_update_bits(rc5t583->regmap, reg, mask, val);
}
static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
int id, int ext_pwr, int slots)
{
......@@ -197,6 +159,7 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id,
ds_id, ext_pwr_req);
return 0;
}
EXPORT_SYMBOL(rc5t583_ext_power_req_config);
static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,
struct rc5t583_platform_data *pdata)
......
......@@ -30,7 +30,9 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/i2c/twl.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/err.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl6040.h>
......@@ -39,7 +41,7 @@
int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
{
int ret;
u8 val = 0;
unsigned int val;
mutex_lock(&twl6040->io_mutex);
/* Vibra control registers from cache */
......@@ -47,7 +49,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
reg == TWL6040_REG_VIBCTLR)) {
val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
} else {
ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
ret = regmap_read(twl6040->regmap, reg, &val);
if (ret < 0) {
mutex_unlock(&twl6040->io_mutex);
return ret;
......@@ -64,7 +66,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
int ret;
mutex_lock(&twl6040->io_mutex);
ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
ret = regmap_write(twl6040->regmap, reg, val);
/* Cache the vibra control registers */
if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
......@@ -77,16 +79,9 @@ EXPORT_SYMBOL(twl6040_reg_write);
int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
{
int ret;
u8 val;
mutex_lock(&twl6040->io_mutex);
ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
if (ret)
goto out;
val |= mask;
ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
out:
ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);
mutex_unlock(&twl6040->io_mutex);
return ret;
}
......@@ -95,16 +90,9 @@ EXPORT_SYMBOL(twl6040_set_bits);
int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
{
int ret;
u8 val;
mutex_lock(&twl6040->io_mutex);
ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
if (ret)
goto out;
val &= ~mask;
ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
out:
ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);
mutex_unlock(&twl6040->io_mutex);
return ret;
}
......@@ -494,32 +482,58 @@ static struct resource twl6040_codec_rsrc[] = {
},
};
static int __devinit twl6040_probe(struct platform_device *pdev)
static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
{
struct twl4030_audio_data *pdata = pdev->dev.platform_data;
/* Register 0 is not readable */
if (!reg)
return false;
return true;
}
static struct regmap_config twl6040_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = TWL6040_REG_STATUS, /* 0x2e */
.readable_reg = twl6040_readable_reg,
};
static int __devinit twl6040_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct twl6040_platform_data *pdata = client->dev.platform_data;
struct twl6040 *twl6040;
struct mfd_cell *cell = NULL;
int ret, children = 0;
if (!pdata) {
dev_err(&pdev->dev, "Platform data is missing\n");
dev_err(&client->dev, "Platform data is missing\n");
return -EINVAL;
}
/* In order to operate correctly we need valid interrupt config */
if (!pdata->naudint_irq || !pdata->irq_base) {
dev_err(&pdev->dev, "Invalid IRQ configuration\n");
if (!client->irq || !pdata->irq_base) {
dev_err(&client->dev, "Invalid IRQ configuration\n");
return -EINVAL;
}
twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL);
if (!twl6040)
return -ENOMEM;
twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
GFP_KERNEL);
if (!twl6040) {
ret = -ENOMEM;
goto err;
}
twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config);
if (IS_ERR(twl6040->regmap)) {
ret = PTR_ERR(twl6040->regmap);
goto err;
}
platform_set_drvdata(pdev, twl6040);
i2c_set_clientdata(client, twl6040);
twl6040->dev = &pdev->dev;
twl6040->irq = pdata->naudint_irq;
twl6040->dev = &client->dev;
twl6040->irq = client->irq;
twl6040->irq_base = pdata->irq_base;
mutex_init(&twl6040->mutex);
......@@ -588,12 +602,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
}
if (children) {
ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells,
ret = mfd_add_devices(&client->dev, -1, twl6040->cells,
children, NULL, 0);
if (ret)
goto mfd_err;
} else {
dev_err(&pdev->dev, "No platform data found for children\n");
dev_err(&client->dev, "No platform data found for children\n");
ret = -ENODEV;
goto mfd_err;
}
......@@ -608,14 +622,15 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
if (gpio_is_valid(twl6040->audpwron))
gpio_free(twl6040->audpwron);
gpio1_err:
platform_set_drvdata(pdev, NULL);
kfree(twl6040);
i2c_set_clientdata(client, NULL);
regmap_exit(twl6040->regmap);
err:
return ret;
}
static int __devexit twl6040_remove(struct platform_device *pdev)
static int __devexit twl6040_remove(struct i2c_client *client)
{
struct twl6040 *twl6040 = platform_get_drvdata(pdev);
struct twl6040 *twl6040 = i2c_get_clientdata(client);
if (twl6040->power_count)
twl6040_power(twl6040, 0);
......@@ -626,23 +641,30 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);
twl6040_irq_exit(twl6040);
mfd_remove_devices(&pdev->dev);
platform_set_drvdata(pdev, NULL);
kfree(twl6040);
mfd_remove_devices(&client->dev);
i2c_set_clientdata(client, NULL);
regmap_exit(twl6040->regmap);
return 0;
}
static struct platform_driver twl6040_driver = {
static const struct i2c_device_id twl6040_i2c_id[] = {
{ "twl6040", 0, },
{ },
};
MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id);
static struct i2c_driver twl6040_driver = {
.driver = {
.name = "twl6040",
.owner = THIS_MODULE,
},
.probe = twl6040_probe,
.remove = __devexit_p(twl6040_remove),
.driver = {
.owner = THIS_MODULE,
.name = "twl6040",
},
.id_table = twl6040_i2c_id,
};
module_platform_driver(twl6040_driver);
module_i2c_driver(twl6040_driver);
MODULE_DESCRIPTION("TWL6040 MFD");
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
......
......@@ -42,6 +42,7 @@
#include <plat/usb.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/gpio.h>
/* EHCI Register Set */
#define EHCI_INSNREG04 (0xA0)
......@@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
}
}
if (pdata->phy_reset) {
if (gpio_is_valid(pdata->reset_gpio_port[0]))
gpio_request_one(pdata->reset_gpio_port[0],
GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
if (gpio_is_valid(pdata->reset_gpio_port[1]))
gpio_request_one(pdata->reset_gpio_port[1],
GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
/* Hold the PHY in RESET for enough time till DIR is high */
udelay(10);
}
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
......@@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
/* root ports should always stay powered */
ehci_port_power(omap_ehci, 1);
if (pdata->phy_reset) {
/* Hold the PHY in RESET for enough time till
* PHY is settled and ready
*/
udelay(10);
if (gpio_is_valid(pdata->reset_gpio_port[0]))
gpio_set_value(pdata->reset_gpio_port[0], 1);
if (gpio_is_valid(pdata->reset_gpio_port[1]))
gpio_set_value(pdata->reset_gpio_port[1], 1);
}
return 0;
err_add_hcd:
......@@ -259,8 +286,9 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
*/
static int ehci_hcd_omap_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct device *dev = &pdev->dev;
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ehci_hcd_omap_platform_data *pdata = dev->platform_data;
usb_remove_hcd(hcd);
disable_put_regulator(dev->platform_data);
......@@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
if (pdata->phy_reset) {
if (gpio_is_valid(pdata->reset_gpio_port[0]))
gpio_free(pdata->reset_gpio_port[0]);
if (gpio_is_valid(pdata->reset_gpio_port[1]))
gpio_free(pdata->reset_gpio_port[1]);
}
return 0;
}
......
......@@ -666,23 +666,11 @@ struct twl4030_codec_data {
unsigned int check_defaults:1;
unsigned int reset_registers:1;
unsigned int hs_extmute:1;
u16 hs_left_step;
u16 hs_right_step;
u16 hf_left_step;
u16 hf_right_step;
void (*set_hs_extmute)(int mute);
};
struct twl4030_vibra_data {
unsigned int coexist;
/* twl6040 */
unsigned int vibldrv_res; /* left driver resistance */
unsigned int vibrdrv_res; /* right driver resistance */
unsigned int viblmotor_res; /* left motor resistance */
unsigned int vibrmotor_res; /* right motor resistance */
int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */
int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */
};
struct twl4030_audio_data {
......
......@@ -8,41 +8,14 @@
#ifndef __MFD_DB5500_PRCMU_H
#define __MFD_DB5500_PRCMU_H
#ifdef CONFIG_MFD_DB5500_PRCMU
void db5500_prcmu_early_init(void);
int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state);
int db5500_prcmu_set_display_clocks(void);
int db5500_prcmu_disable_dsipll(void);
int db5500_prcmu_enable_dsipll(void);
int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
void db5500_prcmu_enable_wakeups(u32 wakeups);
int db5500_prcmu_request_clock(u8 clock, bool enable);
void db5500_prcmu_config_abb_event_readout(u32 abb_events);
void db5500_prcmu_get_abb_event_buffer(void __iomem **buf);
int prcmu_resetout(u8 resoutn, u8 state);
int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
bool keep_ap_pll);
int db5500_prcmu_config_esram0_deep_sleep(u8 state);
void db5500_prcmu_system_reset(u16 reset_code);
u16 db5500_prcmu_get_reset_code(void);
bool db5500_prcmu_is_ac_wake_requested(void);
int db5500_prcmu_set_arm_opp(u8 opp);
int db5500_prcmu_get_arm_opp(void);
#else /* !CONFIG_UX500_SOC_DB5500 */
static inline void db5500_prcmu_early_init(void) {}
static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
static inline int prcmu_resetout(u8 resoutn, u8 state)
{
return -ENOSYS;
return 0;
}
static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)
{
return -ENOSYS;
return 0;
}
static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
......@@ -50,69 +23,82 @@ static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
return 0;
}
static inline int db5500_prcmu_set_display_clocks(void)
static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
bool keep_ap_pll)
{
return 0;
}
static inline int db5500_prcmu_disable_dsipll(void)
static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
{
return 0;
}
static inline int db5500_prcmu_enable_dsipll(void)
static inline u16 db5500_prcmu_get_reset_code(void)
{
return 0;
}
static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
static inline bool db5500_prcmu_is_ac_wake_requested(void)
{
return 0;
}
static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
static inline int prcmu_resetout(u8 resoutn, u8 state)
static inline int db5500_prcmu_set_arm_opp(u8 opp)
{
return 0;
}
static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)
static inline int db5500_prcmu_get_arm_opp(void)
{
return 0;
}
static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {}
static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
bool keep_ap_pll)
{
return 0;
}
static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
static inline void db5500_prcmu_system_reset(u16 reset_code) {}
static inline u16 db5500_prcmu_get_reset_code(void)
static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
#ifdef CONFIG_MFD_DB5500_PRCMU
void db5500_prcmu_early_init(void);
int db5500_prcmu_set_display_clocks(void);
int db5500_prcmu_disable_dsipll(void);
int db5500_prcmu_enable_dsipll(void);
int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
#else /* !CONFIG_UX500_SOC_DB5500 */
static inline void db5500_prcmu_early_init(void) {}
static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
{
return 0;
return -ENOSYS;
}
static inline bool db5500_prcmu_is_ac_wake_requested(void)
static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
{
return 0;
return -ENOSYS;
}
static inline int db5500_prcmu_set_arm_opp(u8 opp)
static inline int db5500_prcmu_set_display_clocks(void)
{
return 0;
}
static inline int db5500_prcmu_get_arm_opp(void)
static inline int db5500_prcmu_disable_dsipll(void)
{
return 0;
}
static inline int db5500_prcmu_enable_dsipll(void)
{
return 0;
}
#endif /* CONFIG_MFD_DB5500_PRCMU */
......
......@@ -26,6 +26,7 @@
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/regmap.h>
#define RC5T583_MAX_REGS 0xF8
......@@ -279,14 +280,44 @@ struct rc5t583_platform_data {
bool enable_shutdown;
};
int rc5t583_write(struct device *dev, u8 reg, uint8_t val);
int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val);
int rc5t583_set_bits(struct device *dev, unsigned int reg,
unsigned int bit_mask);
int rc5t583_clear_bits(struct device *dev, unsigned int reg,
unsigned int bit_mask);
int rc5t583_update(struct device *dev, unsigned int reg,
unsigned int val, unsigned int mask);
static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_write(rc5t583->regmap, reg, val);
}
static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
unsigned int ival;
int ret;
ret = regmap_read(rc5t583->regmap, reg, &ival);
if (!ret)
*val = (uint8_t)ival;
return ret;
}
static inline int rc5t583_set_bits(struct device *dev, unsigned int reg,
unsigned int bit_mask)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
}
static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg,
unsigned int bit_mask)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
}
static inline int rc5t583_update(struct device *dev, unsigned int reg,
unsigned int val, unsigned int mask)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
return regmap_update_bits(rc5t583->regmap, reg, mask, val);
}
int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id,
int ext_pwr_req, int deepsleep_slot_nr);
int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base);
......
......@@ -174,8 +174,35 @@
#define TWL6040_SYSCLK_SEL_LPPLL 0
#define TWL6040_SYSCLK_SEL_HPPLL 1
struct twl6040_codec_data {
u16 hs_left_step;
u16 hs_right_step;
u16 hf_left_step;
u16 hf_right_step;
};
struct twl6040_vibra_data {
unsigned int vibldrv_res; /* left driver resistance */
unsigned int vibrdrv_res; /* right driver resistance */
unsigned int viblmotor_res; /* left motor resistance */
unsigned int vibrmotor_res; /* right motor resistance */
int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */
int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */
};
struct twl6040_platform_data {
int audpwron_gpio; /* audio power-on gpio */
unsigned int irq_base;
struct twl6040_codec_data *codec;
struct twl6040_vibra_data *vibra;
};
struct regmap;
struct twl6040 {
struct device *dev;
struct regmap *regmap;
struct mutex mutex;
struct mutex io_mutex;
struct mutex irq_mutex;
......
......@@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_TPA6130A2 if I2C
select SND_SOC_TLV320DAC33 if I2C
select SND_SOC_TWL4030 if TWL4030_CORE
select SND_SOC_TWL6040 if TWL4030_CORE
select SND_SOC_TWL6040 if TWL6040_CORE
select SND_SOC_UDA134X
select SND_SOC_UDA1380 if I2C
select SND_SOC_WL1273 if MFD_WL1273_CORE
......@@ -276,7 +276,6 @@ config SND_SOC_TWL4030
tristate
config SND_SOC_TWL6040
select TWL6040_CORE
tristate
config SND_SOC_UDA134X
......
......@@ -26,7 +26,6 @@
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/twl6040.h>
#include <sound/core.h>
......@@ -1528,7 +1527,7 @@ static int twl6040_resume(struct snd_soc_codec *codec)
static int twl6040_probe(struct snd_soc_codec *codec)
{
struct twl6040_data *priv;
struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
struct platform_device *pdev = container_of(codec->dev,
struct platform_device, dev);
int ret = 0;
......
......@@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430
config SND_OMAP_SOC_OMAP_ABE_TWL6040
tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4
depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
select SND_OMAP_SOC_DMIC
select SND_OMAP_SOC_MCPDM
select SND_SOC_TWL6040
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册