- Core Frameworks
- New API to call bespoke pre/post IRQ handlers; Regmap - New Device Support - Add support for RN5T567 to rn5t618 - Add support for COMe-cSL6 and COMe-mAL10 to kempld-core - New Functionality - Add support for USB Power Supply to axp20x - Add support for Power Key to hi655x-pmic - Fix-ups - Update MAINTAINERS; Dialog, Altera - Remove module support; max77843, max77620, max8998, max8997, max8925-i2c - Add module support; max14577 - Constifying; max77620 - Allow bespoke IRQ masking/unmasking; max77620 - Remove superfluous code; arizona, qcom_rpm, smsc-ece1099 - Power Management fixups; arizona-core - Error-path improvement; twl-core, dm355evm_msp, smsc-ece1099, hi655x - Clocking fixups; twl6040 - Trivial (spelling, headers, coding-style, whitespace, (re)naming); si476x-i2c, omap-usb-tll, ti_am335x_tscadc, tps6507, hi655x-pmic - Bug Fixes - Fix offset error for MSM8660; qcom_rpm - Fix possible spurious IRQs; arizona, hi655x-pmic -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJXnxUiAAoJEFGvii+H/HdhjY4P/i9EeGo4rSKyMNYvSIV+FwpB W63eOeEf08EzLfaTyDTnJ9FO53UvcJEXvVE7jO5oYWI8g5y5zBinbwk041uUIeuN 5gv/3quW0kiOozd+6VBghaLYbj37ZZLqBFXc0sYpHNwcIrfVboTaiUrFkl9wUXKQ Gbi7mAw0JhgzigQX2oPmylsdJ2u+MuwxLOcL43HoYLQ6E9b5ZmMqHqz0X7zwjh2c og+WYSl2VOe001fRoLZIPPkE6r61IWZ85oojuZKeQnIiadZWXGwY3XMcYDcheVuz 6BC/f5Vt9PacDPjuInfI4Mv8ROmhnvoNgB9xgoUDROAn5m5FgqdHGZPK40hE+uVy cWRQjdI9CiTTcogGepJGY57OlB7T7q+Peue00knjQiiYdtS2jU4E0xNOWPO/8ILD EV8yeYbD9yghhA1vFc5pzOEQnBD9q9zX40N36vJp4cgl6jO25R/PkLeTg5KufFoi 6+H9VAgqevg4/D8R63Yj8ANdEAvTVupLcpzwORgz89jKF4x5fDU782L5nGifx6dt hNlan00bLrSL6sWtAqCvezSNlF2Aqb6qHhdnvIV93VGeteVMU6N1wRB3JH08HFQI C5t+qFqlxJn3R5E8ur/6ZhtkiPnC4qCVR+r9uyH6Aix9bR1W18o0jgypuZMu7E+h czIJMLv97drOVtzYsosz =KB2d -----END PGP SIGNATURE----- Merge tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "Core Framework: - New API to call bespoke pre/post IRQ handlers; Regmap New Device Support: - Add support for RN5T567 to rn5t618 - Add support for COMe-cSL6 and COMe-mAL10 to kempld-core New Functionality: - Add support for USB Power Supply to axp20x - Add support for Power Key to hi655x-pmic Fix-ups: - Update MAINTAINERS; Dialog, Altera - Remove module support; max77843, max77620, max8998, max8997, max8925-i2c - Add module support; max14577 - Constifying; max77620 - Allow bespoke IRQ masking/unmasking; max77620 - Remove superfluous code; arizona, qcom_rpm, smsc-ece1099 - Power Management fixups; arizona-core - Error-path improvement; twl-core, dm355evm_msp, smsc-ece1099, hi655x - Clocking fixups; twl6040 - Trivial (spelling, headers, coding-style, whitespace, (re)naming); si476x-i2c, omap-usb-tll, ti_am335x_tscadc, tps6507, hi655x-pmic Bug Fixes: - Fix offset error for MSM8660; qcom_rpm - Fix possible spurious IRQs; arizona, hi655x-pmic" * tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (42 commits) mfd: qcom_rpm: Parametrize also ack selector size mfd: twl6040: Handle mclk used for HPPLL and optional internal clock source mfd: Add support for COMe-cSL6 and COMe-mAL10 to Kontron PLD driver mfd: hi655x: Fix return value check in hi655x_pmic_probe() mfd: smsc-ece1099: Return directly after a function failure in smsc_i2c_probe() mfd: smsc-ece1099: Delete an unnecessary variable initialisation in smsc_i2c_probe() mfd: dm355evm_msp: Return directly after a failed platform_device_alloc() in add_child() mfd: twl-core: Refactoring for add_numbered_child() mfd: twl-core: Return directly after a failed platform_device_alloc() in add_numbered_child() mfd: arizona: Add missing disable of PM runtime on probe error path mfd: stmpe: Move platform data into MFD driver mfd: max14577: Allow driver to be built as a module mfd: max14577: Use module_init() instead of subsys_initcall() mfd: arizona: Remove some duplicate defines mfd: qcom_rpm: Remove unused define mfd: hi655x-pmic: Add powerkey device to hi655x PMIC driver mfd: hi655x-pmic: Rename some interrupt macro names mfd: hi655x-pmic: Fixup issue with un-acked interrupts mfd: arizona: Check if AOD interrupts are pending before dispatching mfd: qcom_rpm: Fix offset error for msm8660 ...
This commit is contained in:
commit
06e23d5115
@ -19,8 +19,8 @@ Required properties:
|
||||
|
||||
Optional properties, nodes:
|
||||
- enable-active-high: To power on the twl6040 during boot.
|
||||
- clocks: phandle to the clk32k clock provider
|
||||
- clock-names: Must be "clk32k"
|
||||
- clocks: phandle to the clk32k and/or to mclk clock provider
|
||||
- clock-names: Must be "clk32k" for the 32K clock and "mclk" for the MCLK.
|
||||
|
||||
Vibra functionality
|
||||
Required properties:
|
||||
|
11
MAINTAINERS
11
MAINTAINERS
@ -612,6 +612,13 @@ L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/gpio/gpio-altera.c
|
||||
|
||||
ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT
|
||||
M: Thor Thayer <tthayer@opensource.altera.com>
|
||||
S: Maintained
|
||||
F: drivers/gpio/gpio-altera-a10sr.c
|
||||
F: drivers/mfd/altera-a10sr.c
|
||||
F: include/linux/mfd/altera-a10sr.h
|
||||
|
||||
ALTERA TRIPLE SPEED ETHERNET DRIVER
|
||||
M: Vince Bridgers <vbridger@opensource.altera.com>
|
||||
L: netdev@vger.kernel.org
|
||||
@ -3711,6 +3718,8 @@ M: Support Opensource <support.opensource@diasemi.com>
|
||||
W: http://www.dialog-semiconductor.com/products
|
||||
S: Supported
|
||||
F: Documentation/hwmon/da90??
|
||||
F: Documentation/devicetree/bindings/mfd/da90*.txt
|
||||
F: Documentation/devicetree/bindings/regulator/da92*.txt
|
||||
F: Documentation/devicetree/bindings/sound/da[79]*.txt
|
||||
F: drivers/gpio/gpio-da90??.c
|
||||
F: drivers/hwmon/da90??-hwmon.c
|
||||
@ -3731,8 +3740,10 @@ F: drivers/watchdog/da90??_wdt.c
|
||||
F: include/linux/mfd/da903x.h
|
||||
F: include/linux/mfd/da9052/
|
||||
F: include/linux/mfd/da9055/
|
||||
F: include/linux/mfd/da9062/
|
||||
F: include/linux/mfd/da9063/
|
||||
F: include/linux/mfd/da9150/
|
||||
F: include/linux/regulator/da9211.h
|
||||
F: include/sound/da[79]*.h
|
||||
F: sound/soc/codecs/da[79]*.[ch]
|
||||
|
||||
|
@ -18,6 +18,17 @@ config MFD_CS5535
|
||||
This is the core driver for CS5535/CS5536 MFD functions. This is
|
||||
necessary for using the board's GPIO and MFGPT functionality.
|
||||
|
||||
config MFD_ALTERA_A10SR
|
||||
bool "Altera Arria10 DevKit System Resource chip"
|
||||
depends on ARCH_SOCFPGA && SPI_MASTER=y && OF
|
||||
select REGMAP_SPI
|
||||
select MFD_CORE
|
||||
help
|
||||
Support for the Altera Arria10 DevKit MAX5 System Resource chip
|
||||
using the SPI interface. This driver provides common support for
|
||||
accessing the external gpio extender (LEDs & buttons) and
|
||||
power supply alarms (hwmon).
|
||||
|
||||
config MFD_ACT8945A
|
||||
tristate "Active-semi ACT8945A"
|
||||
select MFD_CORE
|
||||
@ -480,6 +491,8 @@ config MFD_KEMPLD
|
||||
* COMe-cDC2 (microETXexpress-DC)
|
||||
* COMe-cHL6
|
||||
* COMe-cPC2 (microETXexpress-PC)
|
||||
* COMe-cSL6
|
||||
* COMe-mAL10
|
||||
* COMe-mBT10
|
||||
* COMe-mCT10
|
||||
* COMe-mTT10 (nanoETXexpress-TT)
|
||||
@ -524,8 +537,8 @@ config MFD_88PM860X
|
||||
battery-charger under the corresponding menus.
|
||||
|
||||
config MFD_MAX14577
|
||||
bool "Maxim Semiconductor MAX14577/77836 MUIC + Charger Support"
|
||||
depends on I2C=y
|
||||
tristate "Maxim Semiconductor MAX14577/77836 MUIC + Charger Support"
|
||||
depends on I2C
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
|
@ -205,3 +205,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
|
||||
intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o
|
||||
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
|
||||
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
|
||||
|
||||
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
|
||||
|
169
drivers/mfd/altera-a10sr.c
Normal file
169
drivers/mfd/altera-a10sr.c
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPI access for Altera Arria10 MAX5 System Resource Chip
|
||||
*
|
||||
* Adapted from DA9052
|
||||
*/
|
||||
|
||||
#include <linux/mfd/altera-a10sr.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
static const struct mfd_cell altr_a10sr_subdev_info[] = {
|
||||
{
|
||||
.name = "altr_a10sr_gpio",
|
||||
.of_compatible = "altr,a10sr-gpio",
|
||||
},
|
||||
};
|
||||
|
||||
static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case ALTR_A10SR_VERSION_READ:
|
||||
case ALTR_A10SR_LED_REG:
|
||||
case ALTR_A10SR_PBDSW_REG:
|
||||
case ALTR_A10SR_PBDSW_IRQ_REG:
|
||||
case ALTR_A10SR_PWR_GOOD1_REG:
|
||||
case ALTR_A10SR_PWR_GOOD2_REG:
|
||||
case ALTR_A10SR_PWR_GOOD3_REG:
|
||||
case ALTR_A10SR_FMCAB_REG:
|
||||
case ALTR_A10SR_HPS_RST_REG:
|
||||
case ALTR_A10SR_USB_QSPI_REG:
|
||||
case ALTR_A10SR_SFPA_REG:
|
||||
case ALTR_A10SR_SFPB_REG:
|
||||
case ALTR_A10SR_I2C_M_REG:
|
||||
case ALTR_A10SR_WARM_RST_REG:
|
||||
case ALTR_A10SR_WR_KEY_REG:
|
||||
case ALTR_A10SR_PMBUS_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case ALTR_A10SR_LED_REG:
|
||||
case ALTR_A10SR_PBDSW_IRQ_REG:
|
||||
case ALTR_A10SR_FMCAB_REG:
|
||||
case ALTR_A10SR_HPS_RST_REG:
|
||||
case ALTR_A10SR_USB_QSPI_REG:
|
||||
case ALTR_A10SR_SFPA_REG:
|
||||
case ALTR_A10SR_SFPB_REG:
|
||||
case ALTR_A10SR_WARM_RST_REG:
|
||||
case ALTR_A10SR_WR_KEY_REG:
|
||||
case ALTR_A10SR_PMBUS_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case ALTR_A10SR_PBDSW_REG:
|
||||
case ALTR_A10SR_PBDSW_IRQ_REG:
|
||||
case ALTR_A10SR_PWR_GOOD1_REG:
|
||||
case ALTR_A10SR_PWR_GOOD2_REG:
|
||||
case ALTR_A10SR_PWR_GOOD3_REG:
|
||||
case ALTR_A10SR_HPS_RST_REG:
|
||||
case ALTR_A10SR_I2C_M_REG:
|
||||
case ALTR_A10SR_WARM_RST_REG:
|
||||
case ALTR_A10SR_WR_KEY_REG:
|
||||
case ALTR_A10SR_PMBUS_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const struct regmap_config altr_a10sr_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.cache_type = REGCACHE_NONE,
|
||||
|
||||
.use_single_rw = true,
|
||||
.read_flag_mask = 1,
|
||||
.write_flag_mask = 0,
|
||||
|
||||
.max_register = ALTR_A10SR_WR_KEY_REG,
|
||||
.readable_reg = altr_a10sr_reg_readable,
|
||||
.writeable_reg = altr_a10sr_reg_writeable,
|
||||
.volatile_reg = altr_a10sr_reg_volatile,
|
||||
|
||||
};
|
||||
|
||||
static int altr_a10sr_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
int ret;
|
||||
struct altr_a10sr *a10sr;
|
||||
|
||||
a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),
|
||||
GFP_KERNEL);
|
||||
if (!a10sr)
|
||||
return -ENOMEM;
|
||||
|
||||
spi->mode = SPI_MODE_3;
|
||||
spi->bits_per_word = 8;
|
||||
spi_setup(spi);
|
||||
|
||||
a10sr->dev = &spi->dev;
|
||||
|
||||
spi_set_drvdata(spi, a10sr);
|
||||
|
||||
a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);
|
||||
if (IS_ERR(a10sr->regmap)) {
|
||||
ret = PTR_ERR(a10sr->regmap);
|
||||
dev_err(&spi->dev, "Failed to allocate register map: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,
|
||||
altr_a10sr_subdev_info,
|
||||
ARRAY_SIZE(altr_a10sr_subdev_info),
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id altr_a10sr_spi_of_match[] = {
|
||||
{ .compatible = "altr,a10sr" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);
|
||||
|
||||
static struct spi_driver altr_a10sr_spi_driver = {
|
||||
.probe = altr_a10sr_spi_probe,
|
||||
.driver = {
|
||||
.name = "altr_a10sr",
|
||||
.of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
module_spi_driver(altr_a10sr_spi_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
|
||||
MODULE_DESCRIPTION("Altera Arria10 DevKit System Resource MFD Driver");
|
@ -1462,7 +1462,7 @@ int arizona_dev_init(struct arizona *arizona)
|
||||
/* Set up for interrupts */
|
||||
ret = arizona_irq_init(arizona);
|
||||
if (ret != 0)
|
||||
goto err_reset;
|
||||
goto err_pm;
|
||||
|
||||
pm_runtime_set_autosuspend_delay(arizona->dev, 100);
|
||||
pm_runtime_use_autosuspend(arizona->dev);
|
||||
@ -1486,6 +1486,8 @@ int arizona_dev_init(struct arizona *arizona)
|
||||
|
||||
err_irq:
|
||||
arizona_irq_exit(arizona);
|
||||
err_pm:
|
||||
pm_runtime_disable(arizona->dev);
|
||||
err_reset:
|
||||
arizona_enable_reset(arizona);
|
||||
regulator_disable(arizona->dcvdd);
|
||||
|
@ -109,8 +109,20 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
|
||||
do {
|
||||
poll = false;
|
||||
|
||||
if (arizona->aod_irq_chip)
|
||||
handle_nested_irq(irq_find_mapping(arizona->virq, 0));
|
||||
if (arizona->aod_irq_chip) {
|
||||
/*
|
||||
* Check the AOD status register to determine whether
|
||||
* the nested IRQ handler should be called.
|
||||
*/
|
||||
ret = regmap_read(arizona->regmap,
|
||||
ARIZONA_AOD_IRQ1, &val);
|
||||
if (ret)
|
||||
dev_warn(arizona->dev,
|
||||
"Failed to read AOD IRQ1 %d\n", ret);
|
||||
else if (val)
|
||||
handle_nested_irq(
|
||||
irq_find_mapping(arizona->virq, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if one of the main interrupts is asserted and only
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
@ -93,7 +94,10 @@ static const struct regmap_range axp22x_writeable_ranges[] = {
|
||||
};
|
||||
|
||||
static const struct regmap_range axp22x_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
|
||||
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
|
||||
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
|
||||
regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp22x_writeable_table = {
|
||||
@ -157,6 +161,11 @@ static struct resource axp20x_usb_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
|
||||
};
|
||||
|
||||
static struct resource axp22x_usb_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
|
||||
};
|
||||
|
||||
static struct resource axp22x_pek_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
@ -524,6 +533,11 @@ static struct mfd_cell axp22x_cells[] = {
|
||||
.resources = axp22x_pek_resources,
|
||||
}, {
|
||||
.name = "axp20x-regulator",
|
||||
}, {
|
||||
.name = "axp20x-usb-power-supply",
|
||||
.of_compatible = "x-powers,axp221-usb-power-supply",
|
||||
.num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
|
||||
.resources = axp22x_usb_power_supply_resources,
|
||||
},
|
||||
};
|
||||
|
||||
@ -664,6 +678,9 @@ static void axp20x_power_off(void)
|
||||
|
||||
regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
|
||||
AXP20X_OFF);
|
||||
|
||||
/* Give capacitors etc. time to drain to avoid kernel panic msg. */
|
||||
msleep(500);
|
||||
}
|
||||
|
||||
int axp20x_match_device(struct axp20x_dev *axp20x)
|
||||
|
@ -199,11 +199,8 @@ static struct device *add_child(struct i2c_client *client, const char *name,
|
||||
int status;
|
||||
|
||||
pdev = platform_device_alloc(name, -1);
|
||||
if (!pdev) {
|
||||
dev_dbg(&client->dev, "can't alloc dev\n");
|
||||
status = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
if (!pdev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
device_init_wakeup(&pdev->dev, can_wakeup);
|
||||
pdev->dev.parent = &client->dev;
|
||||
|
@ -24,19 +24,15 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell hi655x_pmic_devs[] = {
|
||||
{ .name = "hi655x-regulator", },
|
||||
};
|
||||
|
||||
static const struct regmap_irq hi655x_irqs[] = {
|
||||
{ .reg_offset = 0, .mask = OTMP_D1R_INT },
|
||||
{ .reg_offset = 0, .mask = VSYS_2P5_R_INT },
|
||||
{ .reg_offset = 0, .mask = VSYS_UV_D3R_INT },
|
||||
{ .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT },
|
||||
{ .reg_offset = 0, .mask = PWRON_D4SR_INT },
|
||||
{ .reg_offset = 0, .mask = PWRON_D20F_INT },
|
||||
{ .reg_offset = 0, .mask = PWRON_D20R_INT },
|
||||
{ .reg_offset = 0, .mask = RESERVE_INT },
|
||||
{ .reg_offset = 0, .mask = OTMP_D1R_INT_MASK },
|
||||
{ .reg_offset = 0, .mask = VSYS_2P5_R_INT_MASK },
|
||||
{ .reg_offset = 0, .mask = VSYS_UV_D3R_INT_MASK },
|
||||
{ .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT_MASK },
|
||||
{ .reg_offset = 0, .mask = PWRON_D4SR_INT_MASK },
|
||||
{ .reg_offset = 0, .mask = PWRON_D20F_INT_MASK },
|
||||
{ .reg_offset = 0, .mask = PWRON_D20R_INT_MASK },
|
||||
{ .reg_offset = 0, .mask = RESERVE_INT_MASK },
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip hi655x_irq_chip = {
|
||||
@ -45,6 +41,7 @@ static const struct regmap_irq_chip hi655x_irq_chip = {
|
||||
.num_regs = 1,
|
||||
.num_irqs = ARRAY_SIZE(hi655x_irqs),
|
||||
.status_base = HI655X_IRQ_STAT_BASE,
|
||||
.ack_base = HI655X_IRQ_STAT_BASE,
|
||||
.mask_base = HI655X_IRQ_MASK_BASE,
|
||||
};
|
||||
|
||||
@ -55,6 +52,34 @@ static struct regmap_config hi655x_regmap_config = {
|
||||
.max_register = HI655X_BUS_ADDR(0xFFF),
|
||||
};
|
||||
|
||||
static struct resource pwrkey_resources[] = {
|
||||
{
|
||||
.name = "down",
|
||||
.start = PWRON_D20R_INT,
|
||||
.end = PWRON_D20R_INT,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.name = "up",
|
||||
.start = PWRON_D20F_INT,
|
||||
.end = PWRON_D20F_INT,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.name = "hold 4s",
|
||||
.start = PWRON_D4SR_INT,
|
||||
.end = PWRON_D4SR_INT,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell hi655x_pmic_devs[] = {
|
||||
{
|
||||
.name = "hi65xx-powerkey",
|
||||
.num_resources = ARRAY_SIZE(pwrkey_resources),
|
||||
.resources = &pwrkey_resources[0],
|
||||
},
|
||||
{ .name = "hi655x-regulator", },
|
||||
};
|
||||
|
||||
static void hi655x_local_irq_clear(struct regmap *map)
|
||||
{
|
||||
int i;
|
||||
@ -80,12 +105,9 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
|
||||
pmic->dev = dev;
|
||||
|
||||
pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!pmic->res)
|
||||
return -ENOENT;
|
||||
|
||||
base = devm_ioremap_resource(dev, pmic->res);
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
|
||||
&hi655x_regmap_config);
|
||||
@ -123,7 +145,8 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, pmic);
|
||||
|
||||
ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs,
|
||||
ARRAY_SIZE(hi655x_pmic_devs), NULL, 0, NULL);
|
||||
ARRAY_SIZE(hi655x_pmic_devs), NULL, 0,
|
||||
regmap_irq_get_domain(pmic->irq_data));
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register device %d\n", ret);
|
||||
regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
|
||||
|
@ -623,6 +623,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = {
|
||||
},
|
||||
.driver_data = (void *)&kempld_platform_data_generic,
|
||||
.callback = kempld_create_platform_device,
|
||||
}, {
|
||||
.ident = "CSL6",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "COMe-cSL6"),
|
||||
},
|
||||
.driver_data = (void *)&kempld_platform_data_generic,
|
||||
.callback = kempld_create_platform_device,
|
||||
}, {
|
||||
.ident = "CVV6",
|
||||
.matches = {
|
||||
@ -646,6 +654,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = {
|
||||
},
|
||||
.driver_data = (void *)&kempld_platform_data_generic,
|
||||
.callback = kempld_create_platform_device,
|
||||
}, {
|
||||
.ident = "MAL1",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "COMe-mAL10"),
|
||||
},
|
||||
.driver_data = (void *)&kempld_platform_data_generic,
|
||||
.callback = kempld_create_platform_device,
|
||||
}, {
|
||||
.ident = "MBR1",
|
||||
.matches = {
|
||||
|
@ -561,7 +561,7 @@ static int __init max14577_i2c_init(void)
|
||||
|
||||
return i2c_add_driver(&max14577_i2c_driver);
|
||||
}
|
||||
subsys_initcall(max14577_i2c_init);
|
||||
module_init(max14577_i2c_init);
|
||||
|
||||
static void __exit max14577_i2c_exit(void)
|
||||
{
|
||||
|
@ -31,25 +31,25 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/max77620.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static struct resource gpio_resources[] = {
|
||||
static const struct resource gpio_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
|
||||
};
|
||||
|
||||
static struct resource power_resources[] = {
|
||||
static const struct resource power_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW),
|
||||
};
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
static const struct resource rtc_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC),
|
||||
};
|
||||
|
||||
static struct resource thermal_resources[] = {
|
||||
static const struct resource thermal_resources[] = {
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1),
|
||||
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2),
|
||||
};
|
||||
@ -111,15 +111,6 @@ static const struct mfd_cell max20024_children[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip max77620_top_irq_chip = {
|
||||
.name = "max77620-top",
|
||||
.irqs = max77620_top_irqs,
|
||||
.num_irqs = ARRAY_SIZE(max77620_top_irqs),
|
||||
.num_regs = 2,
|
||||
.status_base = MAX77620_REG_IRQTOP,
|
||||
.mask_base = MAX77620_REG_IRQTOPM,
|
||||
};
|
||||
|
||||
static const struct regmap_range max77620_readable_ranges[] = {
|
||||
regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
|
||||
};
|
||||
@ -180,6 +171,51 @@ static const struct regmap_config max20024_regmap_config = {
|
||||
.volatile_table = &max77620_volatile_table,
|
||||
};
|
||||
|
||||
/*
|
||||
* MAX77620 and MAX20024 has the following steps of the interrupt handling
|
||||
* for TOP interrupts:
|
||||
* 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM.
|
||||
* 2. Read IRQTOP and service the interrupt.
|
||||
* 3. Once all interrupts has been checked and serviced, the interrupt service
|
||||
* routine un-masks the hardware interrupt line by clearing GLBLM.
|
||||
*/
|
||||
static int max77620_irq_global_mask(void *irq_drv_data)
|
||||
{
|
||||
struct max77620_chip *chip = irq_drv_data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
|
||||
MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK);
|
||||
if (ret < 0)
|
||||
dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max77620_irq_global_unmask(void *irq_drv_data)
|
||||
{
|
||||
struct max77620_chip *chip = irq_drv_data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
|
||||
MAX77620_GLBLM_MASK, 0);
|
||||
if (ret < 0)
|
||||
dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct regmap_irq_chip max77620_top_irq_chip = {
|
||||
.name = "max77620-top",
|
||||
.irqs = max77620_top_irqs,
|
||||
.num_irqs = ARRAY_SIZE(max77620_top_irqs),
|
||||
.num_regs = 2,
|
||||
.status_base = MAX77620_REG_IRQTOP,
|
||||
.mask_base = MAX77620_REG_IRQTOPM,
|
||||
.handle_pre_irq = max77620_irq_global_mask,
|
||||
.handle_post_irq = max77620_irq_global_unmask,
|
||||
};
|
||||
|
||||
/* max77620_get_fps_period_reg_value: Get FPS bit field value from
|
||||
* requested periods.
|
||||
* MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
|
||||
@ -433,6 +469,7 @@ static int max77620_probe(struct i2c_client *client,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
max77620_top_irq_chip.irq_drv_data = chip;
|
||||
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
chip->irq_base, &max77620_top_irq_chip,
|
||||
@ -568,7 +605,6 @@ static const struct i2c_device_id max77620_id[] = {
|
||||
{"max20024", MAX20024},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max77620_id);
|
||||
|
||||
static const struct dev_pm_ops max77620_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
|
||||
@ -582,11 +618,4 @@ static struct i2c_driver max77620_driver = {
|
||||
.probe = max77620_probe,
|
||||
.id_table = max77620_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(max77620_driver);
|
||||
|
||||
MODULE_DESCRIPTION("MAX77620/MAX20024 Multi Function Device Core Driver");
|
||||
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
|
||||
MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>");
|
||||
MODULE_AUTHOR("Mallikarjun Kasoju <mkasoju@nvidia.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
builtin_i2c_driver(max77620_driver);
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/max77693-common.h>
|
||||
#include <linux/mfd/max77843-private.h>
|
||||
@ -171,19 +171,6 @@ static int max77843_probe(struct i2c_client *i2c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max77843_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(max77843->dev);
|
||||
|
||||
regmap_del_irq_chip(max77843->irq, max77843->irq_data_topsys);
|
||||
|
||||
i2c_unregister_device(max77843->i2c_chg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id max77843_dt_match[] = {
|
||||
{ .compatible = "maxim,max77843", },
|
||||
{ },
|
||||
@ -193,7 +180,6 @@ static const struct i2c_device_id max77843_id[] = {
|
||||
{ "max77843", TYPE_MAX77843, },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max77843_id);
|
||||
|
||||
static int __maybe_unused max77843_suspend(struct device *dev)
|
||||
{
|
||||
@ -226,9 +212,9 @@ static struct i2c_driver max77843_i2c_driver = {
|
||||
.name = "max77843",
|
||||
.pm = &max77843_pm,
|
||||
.of_match_table = max77843_dt_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = max77843_probe,
|
||||
.remove = max77843_remove,
|
||||
.id_table = max77843_id,
|
||||
};
|
||||
|
||||
@ -237,9 +223,3 @@ static int __init max77843_i2c_init(void)
|
||||
return i2c_add_driver(&max77843_i2c_driver);
|
||||
}
|
||||
subsys_initcall(max77843_i2c_init);
|
||||
|
||||
static void __exit max77843_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max77843_i2c_driver);
|
||||
}
|
||||
module_exit(max77843_i2c_exit);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mfd/max8925.h>
|
||||
@ -133,7 +133,6 @@ static const struct i2c_device_id max8925_id_table[] = {
|
||||
{ "max8925", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max8925_id_table);
|
||||
|
||||
static int max8925_dt_init(struct device_node *np, struct device *dev,
|
||||
struct max8925_platform_data *pdata)
|
||||
@ -240,7 +239,6 @@ static const struct of_device_id max8925_dt_ids[] = {
|
||||
{ .compatible = "maxim,max8925", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max8925_dt_ids);
|
||||
|
||||
static struct i2c_driver max8925_driver = {
|
||||
.driver = {
|
||||
@ -264,13 +262,3 @@ static int __init max8925_i2c_init(void)
|
||||
return ret;
|
||||
}
|
||||
subsys_initcall(max8925_i2c_init);
|
||||
|
||||
static void __exit max8925_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max8925_driver);
|
||||
}
|
||||
module_exit(max8925_i2c_exit);
|
||||
|
||||
MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
|
||||
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -2,7 +2,7 @@
|
||||
* max8997.c - mfd core driver for the Maxim 8966 and 8997
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@smasung.com>
|
||||
* MyungJoo Ham <myungjoo.ham@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
|
||||
@ -28,7 +28,7 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/max8997.h>
|
||||
@ -55,7 +55,6 @@ static const struct of_device_id max8997_pmic_dt_match[] = {
|
||||
{ .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max8997_pmic_dt_match);
|
||||
#endif
|
||||
|
||||
int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
|
||||
@ -263,24 +262,11 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max8997_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(max8997->dev);
|
||||
i2c_unregister_device(max8997->muic);
|
||||
i2c_unregister_device(max8997->haptic);
|
||||
i2c_unregister_device(max8997->rtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id max8997_i2c_id[] = {
|
||||
{ "max8997", TYPE_MAX8997 },
|
||||
{ "max8966", TYPE_MAX8966 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
|
||||
|
||||
static u8 max8997_dumpaddr_pmic[] = {
|
||||
MAX8997_REG_INT1MSK,
|
||||
@ -510,10 +496,10 @@ static struct i2c_driver max8997_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max8997",
|
||||
.pm = &max8997_pm,
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = of_match_ptr(max8997_pmic_dt_match),
|
||||
},
|
||||
.probe = max8997_i2c_probe,
|
||||
.remove = max8997_i2c_remove,
|
||||
.id_table = max8997_i2c_id,
|
||||
};
|
||||
|
||||
@ -523,13 +509,3 @@ static int __init max8997_i2c_init(void)
|
||||
}
|
||||
/* init early so consumer devices can complete system boot */
|
||||
subsys_initcall(max8997_i2c_init);
|
||||
|
||||
static void __exit max8997_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max8997_i2c_driver);
|
||||
}
|
||||
module_exit(max8997_i2c_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MAXIM 8997 multi-function core driver");
|
||||
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -21,8 +21,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
@ -138,7 +136,6 @@ static const struct of_device_id max8998_dt_match[] = {
|
||||
{ .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max8998_dt_match);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -254,23 +251,11 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max8998_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
|
||||
|
||||
mfd_remove_devices(max8998->dev);
|
||||
max8998_irq_exit(max8998);
|
||||
i2c_unregister_device(max8998->rtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id max8998_i2c_id[] = {
|
||||
{ "max8998", TYPE_MAX8998 },
|
||||
{ "lp3974", TYPE_LP3974},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
|
||||
|
||||
static int max8998_suspend(struct device *dev)
|
||||
{
|
||||
@ -378,10 +363,10 @@ static struct i2c_driver max8998_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max8998",
|
||||
.pm = &max8998_pm,
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = of_match_ptr(max8998_dt_match),
|
||||
},
|
||||
.probe = max8998_i2c_probe,
|
||||
.remove = max8998_i2c_remove,
|
||||
.id_table = max8998_i2c_id,
|
||||
};
|
||||
|
||||
@ -391,13 +376,3 @@ static int __init max8998_i2c_init(void)
|
||||
}
|
||||
/* init early so consumer devices can complete system boot */
|
||||
subsys_initcall(max8998_i2c_init);
|
||||
|
||||
static void __exit max8998_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max8998_i2c_driver);
|
||||
}
|
||||
module_exit(max8998_i2c_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MAXIM 8998 multi-function core driver");
|
||||
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <linux/platform_data/usb-omap.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "omap-usb.h"
|
||||
|
||||
#define USBTLL_DRIVER_NAME "usbhs_tll"
|
||||
|
||||
/* TLL Register Set */
|
||||
|
@ -34,7 +34,13 @@ struct qcom_rpm_resource {
|
||||
struct qcom_rpm_data {
|
||||
u32 version;
|
||||
const struct qcom_rpm_resource *resource_table;
|
||||
unsigned n_resources;
|
||||
unsigned int n_resources;
|
||||
unsigned int req_ctx_off;
|
||||
unsigned int req_sel_off;
|
||||
unsigned int ack_ctx_off;
|
||||
unsigned int ack_sel_off;
|
||||
unsigned int req_sel_size;
|
||||
unsigned int ack_sel_size;
|
||||
};
|
||||
|
||||
struct qcom_rpm {
|
||||
@ -61,17 +67,11 @@ struct qcom_rpm {
|
||||
|
||||
#define RPM_REQUEST_TIMEOUT (5 * HZ)
|
||||
|
||||
#define RPM_REQUEST_CONTEXT 3
|
||||
#define RPM_REQ_SELECT 11
|
||||
#define RPM_ACK_CONTEXT 15
|
||||
#define RPM_ACK_SELECTOR 23
|
||||
#define RPM_SELECT_SIZE 7
|
||||
#define RPM_MAX_SEL_SIZE 7
|
||||
|
||||
#define RPM_NOTIFICATION BIT(30)
|
||||
#define RPM_REJECTED BIT(31)
|
||||
|
||||
#define RPM_SIGNAL BIT(2)
|
||||
|
||||
static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = {
|
||||
[QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
|
||||
[QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 },
|
||||
@ -157,6 +157,12 @@ static const struct qcom_rpm_data apq8064_template = {
|
||||
.version = 3,
|
||||
.resource_table = apq8064_rpm_resource_table,
|
||||
.n_resources = ARRAY_SIZE(apq8064_rpm_resource_table),
|
||||
.req_ctx_off = 3,
|
||||
.req_sel_off = 11,
|
||||
.ack_ctx_off = 15,
|
||||
.ack_sel_off = 23,
|
||||
.req_sel_size = 4,
|
||||
.ack_sel_size = 7,
|
||||
};
|
||||
|
||||
static const struct qcom_rpm_resource msm8660_rpm_resource_table[] = {
|
||||
@ -240,6 +246,12 @@ static const struct qcom_rpm_data msm8660_template = {
|
||||
.version = 2,
|
||||
.resource_table = msm8660_rpm_resource_table,
|
||||
.n_resources = ARRAY_SIZE(msm8660_rpm_resource_table),
|
||||
.req_ctx_off = 3,
|
||||
.req_sel_off = 11,
|
||||
.ack_ctx_off = 19,
|
||||
.ack_sel_off = 27,
|
||||
.req_sel_size = 7,
|
||||
.ack_sel_size = 7,
|
||||
};
|
||||
|
||||
static const struct qcom_rpm_resource msm8960_rpm_resource_table[] = {
|
||||
@ -322,6 +334,12 @@ static const struct qcom_rpm_data msm8960_template = {
|
||||
.version = 3,
|
||||
.resource_table = msm8960_rpm_resource_table,
|
||||
.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
|
||||
.req_ctx_off = 3,
|
||||
.req_sel_off = 11,
|
||||
.ack_ctx_off = 15,
|
||||
.ack_sel_off = 23,
|
||||
.req_sel_size = 4,
|
||||
.ack_sel_size = 7,
|
||||
};
|
||||
|
||||
static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = {
|
||||
@ -362,6 +380,12 @@ static const struct qcom_rpm_data ipq806x_template = {
|
||||
.version = 3,
|
||||
.resource_table = ipq806x_rpm_resource_table,
|
||||
.n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table),
|
||||
.req_ctx_off = 3,
|
||||
.req_sel_off = 11,
|
||||
.ack_ctx_off = 15,
|
||||
.ack_sel_off = 23,
|
||||
.req_sel_size = 4,
|
||||
.ack_sel_size = 7,
|
||||
};
|
||||
|
||||
static const struct of_device_id qcom_rpm_of_match[] = {
|
||||
@ -380,7 +404,7 @@ int qcom_rpm_write(struct qcom_rpm *rpm,
|
||||
{
|
||||
const struct qcom_rpm_resource *res;
|
||||
const struct qcom_rpm_data *data = rpm->data;
|
||||
u32 sel_mask[RPM_SELECT_SIZE] = { 0 };
|
||||
u32 sel_mask[RPM_MAX_SEL_SIZE] = { 0 };
|
||||
int left;
|
||||
int ret = 0;
|
||||
int i;
|
||||
@ -398,12 +422,12 @@ int qcom_rpm_write(struct qcom_rpm *rpm,
|
||||
writel_relaxed(buf[i], RPM_REQ_REG(rpm, res->target_id + i));
|
||||
|
||||
bitmap_set((unsigned long *)sel_mask, res->select_id, 1);
|
||||
for (i = 0; i < ARRAY_SIZE(sel_mask); i++) {
|
||||
for (i = 0; i < rpm->data->req_sel_size; i++) {
|
||||
writel_relaxed(sel_mask[i],
|
||||
RPM_CTRL_REG(rpm, RPM_REQ_SELECT + i));
|
||||
RPM_CTRL_REG(rpm, rpm->data->req_sel_off + i));
|
||||
}
|
||||
|
||||
writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, RPM_REQUEST_CONTEXT));
|
||||
writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, rpm->data->req_ctx_off));
|
||||
|
||||
reinit_completion(&rpm->ack);
|
||||
regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit));
|
||||
@ -426,10 +450,11 @@ static irqreturn_t qcom_rpm_ack_interrupt(int irq, void *dev)
|
||||
u32 ack;
|
||||
int i;
|
||||
|
||||
ack = readl_relaxed(RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
|
||||
for (i = 0; i < RPM_SELECT_SIZE; i++)
|
||||
writel_relaxed(0, RPM_CTRL_REG(rpm, RPM_ACK_SELECTOR + i));
|
||||
writel(0, RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
|
||||
ack = readl_relaxed(RPM_CTRL_REG(rpm, rpm->data->ack_ctx_off));
|
||||
for (i = 0; i < rpm->data->ack_sel_size; i++)
|
||||
writel_relaxed(0,
|
||||
RPM_CTRL_REG(rpm, rpm->data->ack_sel_off + i));
|
||||
writel(0, RPM_CTRL_REG(rpm, rpm->data->ack_ctx_off));
|
||||
|
||||
if (ack & RPM_NOTIFICATION) {
|
||||
dev_warn(rpm->dev, "ignoring notification!\n");
|
||||
|
@ -600,7 +600,7 @@ static int si476x_core_fwver_to_revision(struct si476x_core *core,
|
||||
unknown_revision:
|
||||
dev_err(&core->client->dev,
|
||||
"Unsupported version of the firmware: %d.%d.%d, "
|
||||
"reverting to A10 comptible functions\n",
|
||||
"reverting to A10 compatible functions\n",
|
||||
major, minor1, minor2);
|
||||
|
||||
return SI476X_REVISION_A10;
|
||||
|
@ -36,7 +36,7 @@ static int smsc_i2c_probe(struct i2c_client *i2c,
|
||||
{
|
||||
struct smsc *smsc;
|
||||
int devid, rev, venid_l, venid_h;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc),
|
||||
GFP_KERNEL);
|
||||
@ -46,10 +46,8 @@ static int smsc_i2c_probe(struct i2c_client *i2c,
|
||||
}
|
||||
|
||||
smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
|
||||
if (IS_ERR(smsc->regmap)) {
|
||||
ret = PTR_ERR(smsc->regmap);
|
||||
goto err;
|
||||
}
|
||||
if (IS_ERR(smsc->regmap))
|
||||
return PTR_ERR(smsc->regmap);
|
||||
|
||||
i2c_set_clientdata(i2c, smsc);
|
||||
smsc->dev = &i2c->dev;
|
||||
@ -68,7 +66,7 @@ static int smsc_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
ret = regmap_write(smsc->regmap, SMSC_CLK_CTRL, smsc->clk);
|
||||
if (ret)
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
if (i2c->dev.of_node)
|
||||
@ -76,7 +74,6 @@ static int smsc_i2c_probe(struct i2c_client *i2c,
|
||||
NULL, NULL, &i2c->dev);
|
||||
#endif
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,27 @@
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include "stmpe.h"
|
||||
|
||||
/**
|
||||
* struct stmpe_platform_data - STMPE platform data
|
||||
* @id: device id to distinguish between multiple STMPEs on the same board
|
||||
* @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*)
|
||||
* @irq_trigger: IRQ trigger to use for the interrupt to the host
|
||||
* @autosleep: bool to enable/disable stmpe autosleep
|
||||
* @autosleep_timeout: inactivity timeout in milliseconds for autosleep
|
||||
* @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)
|
||||
*/
|
||||
struct stmpe_platform_data {
|
||||
int id;
|
||||
unsigned int blocks;
|
||||
unsigned int irq_trigger;
|
||||
bool autosleep;
|
||||
bool irq_over_gpio;
|
||||
int irq_gpio;
|
||||
int autosleep_timeout;
|
||||
};
|
||||
|
||||
static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
|
||||
{
|
||||
return stmpe->variant->enable(stmpe, blocks, true);
|
||||
@ -1187,24 +1208,19 @@ static void stmpe_of_probe(struct stmpe_platform_data *pdata,
|
||||
/* Called from client specific probe routines */
|
||||
int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum)
|
||||
{
|
||||
struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
|
||||
struct stmpe_platform_data *pdata;
|
||||
struct device_node *np = ci->dev->of_node;
|
||||
struct stmpe *stmpe;
|
||||
int ret;
|
||||
|
||||
if (!pdata) {
|
||||
if (!np)
|
||||
return -EINVAL;
|
||||
pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
stmpe_of_probe(pdata, np);
|
||||
|
||||
stmpe_of_probe(pdata, np);
|
||||
|
||||
if (of_find_property(np, "interrupts", NULL) == NULL)
|
||||
ci->irq = -1;
|
||||
}
|
||||
if (of_find_property(np, "interrupts", NULL) == NULL)
|
||||
ci->irq = -1;
|
||||
|
||||
stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL);
|
||||
if (!stmpe)
|
||||
|
@ -27,20 +27,6 @@
|
||||
|
||||
#include <linux/mfd/ti_am335x_tscadc.h>
|
||||
|
||||
static unsigned int tscadc_readl(struct ti_tscadc_dev *tsadc, unsigned int reg)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
regmap_read(tsadc->regmap_tscadc, reg, &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void tscadc_writel(struct ti_tscadc_dev *tsadc, unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
regmap_write(tsadc->regmap_tscadc, reg, val);
|
||||
}
|
||||
|
||||
static const struct regmap_config tscadc_regmap_config = {
|
||||
.name = "ti_tscadc",
|
||||
.reg_bits = 32,
|
||||
@ -48,89 +34,89 @@ static const struct regmap_config tscadc_regmap_config = {
|
||||
.val_bits = 32,
|
||||
};
|
||||
|
||||
void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val)
|
||||
void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tscadc, u32 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tsadc->reg_lock, flags);
|
||||
tsadc->reg_se_cache |= val;
|
||||
if (tsadc->adc_waiting)
|
||||
wake_up(&tsadc->reg_se_wait);
|
||||
else if (!tsadc->adc_in_use)
|
||||
tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
|
||||
spin_lock_irqsave(&tscadc->reg_lock, flags);
|
||||
tscadc->reg_se_cache |= val;
|
||||
if (tscadc->adc_waiting)
|
||||
wake_up(&tscadc->reg_se_wait);
|
||||
else if (!tscadc->adc_in_use)
|
||||
regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
|
||||
|
||||
spin_unlock_irqrestore(&tsadc->reg_lock, flags);
|
||||
spin_unlock_irqrestore(&tscadc->reg_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache);
|
||||
|
||||
static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tsadc)
|
||||
static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tscadc)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
u32 reg;
|
||||
|
||||
reg = tscadc_readl(tsadc, REG_ADCFSM);
|
||||
regmap_read(tscadc->regmap, REG_ADCFSM, ®);
|
||||
if (reg & SEQ_STATUS) {
|
||||
tsadc->adc_waiting = true;
|
||||
prepare_to_wait(&tsadc->reg_se_wait, &wait,
|
||||
tscadc->adc_waiting = true;
|
||||
prepare_to_wait(&tscadc->reg_se_wait, &wait,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
spin_unlock_irq(&tsadc->reg_lock);
|
||||
spin_unlock_irq(&tscadc->reg_lock);
|
||||
|
||||
schedule();
|
||||
|
||||
spin_lock_irq(&tsadc->reg_lock);
|
||||
finish_wait(&tsadc->reg_se_wait, &wait);
|
||||
spin_lock_irq(&tscadc->reg_lock);
|
||||
finish_wait(&tscadc->reg_se_wait, &wait);
|
||||
|
||||
/*
|
||||
* Sequencer should either be idle or
|
||||
* busy applying the charge step.
|
||||
*/
|
||||
reg = tscadc_readl(tsadc, REG_ADCFSM);
|
||||
regmap_read(tscadc->regmap, REG_ADCFSM, ®);
|
||||
WARN_ON((reg & SEQ_STATUS) && !(reg & CHARGE_STEP));
|
||||
tsadc->adc_waiting = false;
|
||||
tscadc->adc_waiting = false;
|
||||
}
|
||||
tsadc->adc_in_use = true;
|
||||
tscadc->adc_in_use = true;
|
||||
}
|
||||
|
||||
void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val)
|
||||
void am335x_tsc_se_set_once(struct ti_tscadc_dev *tscadc, u32 val)
|
||||
{
|
||||
spin_lock_irq(&tsadc->reg_lock);
|
||||
am335x_tscadc_need_adc(tsadc);
|
||||
spin_lock_irq(&tscadc->reg_lock);
|
||||
am335x_tscadc_need_adc(tscadc);
|
||||
|
||||
tscadc_writel(tsadc, REG_SE, val);
|
||||
spin_unlock_irq(&tsadc->reg_lock);
|
||||
regmap_write(tscadc->regmap, REG_SE, val);
|
||||
spin_unlock_irq(&tscadc->reg_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once);
|
||||
|
||||
void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tsadc)
|
||||
void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tscadc)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tsadc->reg_lock, flags);
|
||||
tsadc->adc_in_use = false;
|
||||
tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
|
||||
spin_unlock_irqrestore(&tsadc->reg_lock, flags);
|
||||
spin_lock_irqsave(&tscadc->reg_lock, flags);
|
||||
tscadc->adc_in_use = false;
|
||||
regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
|
||||
spin_unlock_irqrestore(&tscadc->reg_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done);
|
||||
|
||||
void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
|
||||
void am335x_tsc_se_clr(struct ti_tscadc_dev *tscadc, u32 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tsadc->reg_lock, flags);
|
||||
tsadc->reg_se_cache &= ~val;
|
||||
tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
|
||||
spin_unlock_irqrestore(&tsadc->reg_lock, flags);
|
||||
spin_lock_irqsave(&tscadc->reg_lock, flags);
|
||||
tscadc->reg_se_cache &= ~val;
|
||||
regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
|
||||
spin_unlock_irqrestore(&tscadc->reg_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
|
||||
|
||||
static void tscadc_idle_config(struct ti_tscadc_dev *config)
|
||||
static void tscadc_idle_config(struct ti_tscadc_dev *tscadc)
|
||||
{
|
||||
unsigned int idleconfig;
|
||||
|
||||
idleconfig = STEPCONFIG_YNN | STEPCONFIG_INM_ADCREFM |
|
||||
STEPCONFIG_INP_ADCREFM | STEPCONFIG_YPN;
|
||||
|
||||
tscadc_writel(config, REG_IDLECONFIG, idleconfig);
|
||||
regmap_write(tscadc->regmap, REG_IDLECONFIG, idleconfig);
|
||||
}
|
||||
|
||||
static int ti_tscadc_probe(struct platform_device *pdev)
|
||||
@ -182,8 +168,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Allocate memory for device */
|
||||
tscadc = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct ti_tscadc_dev), GFP_KERNEL);
|
||||
tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
|
||||
if (!tscadc) {
|
||||
dev_err(&pdev->dev, "failed to allocate memory.\n");
|
||||
return -ENOMEM;
|
||||
@ -202,11 +187,11 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(tscadc->tscadc_base))
|
||||
return PTR_ERR(tscadc->tscadc_base);
|
||||
|
||||
tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev,
|
||||
tscadc->regmap = devm_regmap_init_mmio(&pdev->dev,
|
||||
tscadc->tscadc_base, &tscadc_regmap_config);
|
||||
if (IS_ERR(tscadc->regmap_tscadc)) {
|
||||
if (IS_ERR(tscadc->regmap)) {
|
||||
dev_err(&pdev->dev, "regmap init failed\n");
|
||||
err = PTR_ERR(tscadc->regmap_tscadc);
|
||||
err = PTR_ERR(tscadc->regmap);
|
||||
goto ret;
|
||||
}
|
||||
|
||||
@ -236,11 +221,11 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||
|
||||
/* TSCADC_CLKDIV needs to be configured to the value minus 1 */
|
||||
tscadc->clk_div--;
|
||||
tscadc_writel(tscadc, REG_CLKDIV, tscadc->clk_div);
|
||||
regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div);
|
||||
|
||||
/* Set the control register bits */
|
||||
ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID;
|
||||
tscadc_writel(tscadc, REG_CTRL, ctrl);
|
||||
regmap_write(tscadc->regmap, REG_CTRL, ctrl);
|
||||
|
||||
/* Set register bits for Idle Config Mode */
|
||||
if (tsc_wires > 0) {
|
||||
@ -254,7 +239,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||
|
||||
/* Enable the TSC module enable bit */
|
||||
ctrl |= CNTRLREG_TSCSSENB;
|
||||
tscadc_writel(tscadc, REG_CTRL, ctrl);
|
||||
regmap_write(tscadc->regmap, REG_CTRL, ctrl);
|
||||
|
||||
tscadc->used_cells = 0;
|
||||
tscadc->tsc_cell = -1;
|
||||
@ -300,7 +285,7 @@ static int ti_tscadc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ti_tscadc_dev *tscadc = platform_get_drvdata(pdev);
|
||||
|
||||
tscadc_writel(tscadc, REG_SE, 0x00);
|
||||
regmap_write(tscadc->regmap, REG_SE, 0x00);
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
@ -310,51 +295,43 @@ static int ti_tscadc_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int tscadc_suspend(struct device *dev)
|
||||
static int __maybe_unused tscadc_suspend(struct device *dev)
|
||||
{
|
||||
struct ti_tscadc_dev *tscadc_dev = dev_get_drvdata(dev);
|
||||
struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
|
||||
|
||||
tscadc_writel(tscadc_dev, REG_SE, 0x00);
|
||||
regmap_write(tscadc->regmap, REG_SE, 0x00);
|
||||
pm_runtime_put_sync(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tscadc_resume(struct device *dev)
|
||||
static int __maybe_unused tscadc_resume(struct device *dev)
|
||||
{
|
||||
struct ti_tscadc_dev *tscadc_dev = dev_get_drvdata(dev);
|
||||
struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
|
||||
u32 ctrl;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
/* context restore */
|
||||
ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID;
|
||||
tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
|
||||
regmap_write(tscadc->regmap, REG_CTRL, ctrl);
|
||||
|
||||
if (tscadc_dev->tsc_cell != -1) {
|
||||
if (tscadc_dev->tsc_wires == 5)
|
||||
if (tscadc->tsc_cell != -1) {
|
||||
if (tscadc->tsc_wires == 5)
|
||||
ctrl |= CNTRLREG_5WIRE | CNTRLREG_TSCENB;
|
||||
else
|
||||
ctrl |= CNTRLREG_4WIRE | CNTRLREG_TSCENB;
|
||||
tscadc_idle_config(tscadc_dev);
|
||||
tscadc_idle_config(tscadc);
|
||||
}
|
||||
ctrl |= CNTRLREG_TSCSSENB;
|
||||
tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
|
||||
regmap_write(tscadc->regmap, REG_CTRL, ctrl);
|
||||
|
||||
tscadc_writel(tscadc_dev, REG_CLKDIV, tscadc_dev->clk_div);
|
||||
regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops tscadc_pm_ops = {
|
||||
.suspend = tscadc_suspend,
|
||||
.resume = tscadc_resume,
|
||||
};
|
||||
#define TSCADC_PM_OPS (&tscadc_pm_ops)
|
||||
#else
|
||||
#define TSCADC_PM_OPS NULL
|
||||
#endif
|
||||
static SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume);
|
||||
|
||||
static const struct of_device_id ti_tscadc_dt_ids[] = {
|
||||
{ .compatible = "ti,am3359-tscadc", },
|
||||
@ -365,7 +342,7 @@ MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
|
||||
static struct platform_driver ti_tscadc_driver = {
|
||||
.driver = {
|
||||
.name = "ti_am3359-tscadc",
|
||||
.pm = TSCADC_PM_OPS,
|
||||
.pm = &tscadc_pm_ops,
|
||||
.of_match_table = ti_tscadc_dt_ids,
|
||||
},
|
||||
.probe = ti_tscadc_probe,
|
||||
|
@ -105,8 +105,8 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c,
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps6507x_i2c_id[] = {
|
||||
{ "tps6507x", 0 },
|
||||
{ }
|
||||
{ "tps6507x", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id);
|
||||
|
||||
|
@ -622,11 +622,8 @@ add_numbered_child(unsigned mod_no, const char *name, int num,
|
||||
twl = &twl_priv->twl_modules[sid];
|
||||
|
||||
pdev = platform_device_alloc(name, num);
|
||||
if (!pdev) {
|
||||
dev_dbg(&twl->client->dev, "can't alloc dev\n");
|
||||
status = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
if (!pdev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pdev->dev.parent = &twl->client->dev;
|
||||
|
||||
@ -634,7 +631,7 @@ add_numbered_child(unsigned mod_no, const char *name, int num,
|
||||
status = platform_device_add_data(pdev, pdata, pdata_len);
|
||||
if (status < 0) {
|
||||
dev_dbg(&pdev->dev, "can't add platform_data\n");
|
||||
goto err;
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
@ -647,21 +644,22 @@ add_numbered_child(unsigned mod_no, const char *name, int num,
|
||||
status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
|
||||
if (status < 0) {
|
||||
dev_dbg(&pdev->dev, "can't add irqs\n");
|
||||
goto err;
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
status = platform_device_add(pdev);
|
||||
if (status == 0)
|
||||
device_init_wakeup(&pdev->dev, can_wakeup);
|
||||
if (status)
|
||||
goto put_device;
|
||||
|
||||
device_init_wakeup(&pdev->dev, can_wakeup);
|
||||
|
||||
err:
|
||||
if (status < 0) {
|
||||
platform_device_put(pdev);
|
||||
dev_err(&twl->client->dev, "can't add %s dev\n", name);
|
||||
return ERR_PTR(status);
|
||||
}
|
||||
return &pdev->dev;
|
||||
|
||||
put_device:
|
||||
platform_device_put(pdev);
|
||||
dev_err(&twl->client->dev, "failed to add device %s\n", name);
|
||||
return ERR_PTR(status);
|
||||
}
|
||||
|
||||
static inline struct device *add_child(unsigned mod_no, const char *name,
|
||||
|
@ -323,8 +323,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
||||
|
||||
/* Default PLL configuration after power up */
|
||||
twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
|
||||
twl6040->sysclk = 19200000;
|
||||
twl6040->mclk = 32768;
|
||||
twl6040->sysclk_rate = 19200000;
|
||||
} else {
|
||||
/* already powered-down */
|
||||
if (!twl6040->power_count) {
|
||||
@ -352,8 +351,12 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
||||
regcache_cache_only(twl6040->regmap, true);
|
||||
regcache_mark_dirty(twl6040->regmap);
|
||||
|
||||
twl6040->sysclk = 0;
|
||||
twl6040->mclk = 0;
|
||||
twl6040->sysclk_rate = 0;
|
||||
|
||||
if (twl6040->pll == TWL6040_SYSCLK_SEL_HPPLL) {
|
||||
clk_disable_unprepare(twl6040->mclk);
|
||||
twl6040->mclk_rate = 0;
|
||||
}
|
||||
|
||||
clk_disable_unprepare(twl6040->clk32k);
|
||||
}
|
||||
@ -377,15 +380,15 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
||||
|
||||
/* Force full reconfiguration when switching between PLL */
|
||||
if (pll_id != twl6040->pll) {
|
||||
twl6040->sysclk = 0;
|
||||
twl6040->mclk = 0;
|
||||
twl6040->sysclk_rate = 0;
|
||||
twl6040->mclk_rate = 0;
|
||||
}
|
||||
|
||||
switch (pll_id) {
|
||||
case TWL6040_SYSCLK_SEL_LPPLL:
|
||||
/* low-power PLL divider */
|
||||
/* Change the sysclk configuration only if it has been canged */
|
||||
if (twl6040->sysclk != freq_out) {
|
||||
if (twl6040->sysclk_rate != freq_out) {
|
||||
switch (freq_out) {
|
||||
case 17640000:
|
||||
lppllctl |= TWL6040_LPLLFIN;
|
||||
@ -427,6 +430,8 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
||||
ret = -EINVAL;
|
||||
goto pll_out;
|
||||
}
|
||||
|
||||
clk_disable_unprepare(twl6040->mclk);
|
||||
break;
|
||||
case TWL6040_SYSCLK_SEL_HPPLL:
|
||||
/* high-performance PLL can provide only 19.2 MHz */
|
||||
@ -437,7 +442,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
||||
goto pll_out;
|
||||
}
|
||||
|
||||
if (twl6040->mclk != freq_in) {
|
||||
if (twl6040->mclk_rate != freq_in) {
|
||||
hppllctl &= ~TWL6040_MCLK_MSK;
|
||||
|
||||
switch (freq_in) {
|
||||
@ -468,6 +473,9 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
||||
goto pll_out;
|
||||
}
|
||||
|
||||
/* When switching to HPPLL, enable the mclk first */
|
||||
if (pll_id != twl6040->pll)
|
||||
clk_prepare_enable(twl6040->mclk);
|
||||
/*
|
||||
* enable clock slicer to ensure input waveform is
|
||||
* square
|
||||
@ -483,6 +491,8 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
||||
lppllctl &= ~TWL6040_LPLLENA;
|
||||
twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
|
||||
lppllctl);
|
||||
|
||||
twl6040->mclk_rate = freq_in;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -491,8 +501,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
||||
goto pll_out;
|
||||
}
|
||||
|
||||
twl6040->sysclk = freq_out;
|
||||
twl6040->mclk = freq_in;
|
||||
twl6040->sysclk_rate = freq_out;
|
||||
twl6040->pll = pll_id;
|
||||
|
||||
pll_out:
|
||||
@ -512,7 +521,7 @@ EXPORT_SYMBOL(twl6040_get_pll);
|
||||
|
||||
unsigned int twl6040_get_sysclk(struct twl6040 *twl6040)
|
||||
{
|
||||
return twl6040->sysclk;
|
||||
return twl6040->sysclk_rate;
|
||||
}
|
||||
EXPORT_SYMBOL(twl6040_get_sysclk);
|
||||
|
||||
@ -655,10 +664,18 @@ static int twl6040_probe(struct i2c_client *client,
|
||||
if (IS_ERR(twl6040->clk32k)) {
|
||||
if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
dev_info(&client->dev, "clk32k is not handled\n");
|
||||
dev_dbg(&client->dev, "clk32k is not handled\n");
|
||||
twl6040->clk32k = NULL;
|
||||
}
|
||||
|
||||
twl6040->mclk = devm_clk_get(&client->dev, "mclk");
|
||||
if (IS_ERR(twl6040->mclk)) {
|
||||
if (PTR_ERR(twl6040->mclk) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
dev_dbg(&client->dev, "mclk is not handled\n");
|
||||
twl6040->mclk = NULL;
|
||||
}
|
||||
|
||||
twl6040->supplies[0].supply = "vio";
|
||||
twl6040->supplies[1].supply = "v2v1";
|
||||
ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES,
|
||||
|
85
include/linux/mfd/altera-a10sr.h
Normal file
85
include/linux/mfd/altera-a10sr.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Declarations for Altera Arria10 MAX5 System Resource Chip
|
||||
*
|
||||
* Adapted from DA9052
|
||||
*/
|
||||
|
||||
#ifndef __MFD_ALTERA_A10SR_H
|
||||
#define __MFD_ALTERA_A10SR_H
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* Write registers are always on even addresses */
|
||||
#define WRITE_REG_MASK 0xFE
|
||||
/* Odd registers are always on odd addresses */
|
||||
#define READ_REG_MASK 0x01
|
||||
|
||||
#define ALTR_A10SR_BITS_PER_REGISTER 8
|
||||
/*
|
||||
* To find the correct register, we divide the input GPIO by
|
||||
* the number of GPIO in each register. We then need to multiply
|
||||
* by 2 because the reads are at odd addresses.
|
||||
*/
|
||||
#define ALTR_A10SR_REG_OFFSET(X) (((X) / ALTR_A10SR_BITS_PER_REGISTER) << 1)
|
||||
#define ALTR_A10SR_REG_BIT(X) ((X) % ALTR_A10SR_BITS_PER_REGISTER)
|
||||
#define ALTR_A10SR_REG_BIT_CHG(X, Y) ((X) << ALTR_A10SR_REG_BIT(Y))
|
||||
#define ALTR_A10SR_REG_BIT_MASK(X) (1 << ALTR_A10SR_REG_BIT(X))
|
||||
|
||||
/* Arria10 System Controller Register Defines */
|
||||
#define ALTR_A10SR_NOP 0x00 /* No Change */
|
||||
#define ALTR_A10SR_VERSION_READ 0x00 /* MAX5 Version Read */
|
||||
|
||||
#define ALTR_A10SR_LED_REG 0x02 /* LED - Upper 4 bits */
|
||||
/* LED register Bit Definitions */
|
||||
#define ALTR_A10SR_LED_VALID_SHIFT 4 /* LED - Upper 4 bits valid */
|
||||
#define ALTR_A10SR_OUT_VALID_RANGE_LO ALTR_A10SR_LED_VALID_SHIFT
|
||||
#define ALTR_A10SR_OUT_VALID_RANGE_HI 7
|
||||
|
||||
#define ALTR_A10SR_PBDSW_REG 0x04 /* PB & DIP SW - Input only */
|
||||
#define ALTR_A10SR_PBDSW_IRQ_REG 0x06 /* PB & DIP SW Flag Clear */
|
||||
/* Pushbutton & DIP Switch Bit Definitions */
|
||||
#define ALTR_A10SR_IN_VALID_RANGE_LO 8
|
||||
#define ALTR_A10SR_IN_VALID_RANGE_HI 15
|
||||
|
||||
#define ALTR_A10SR_PWR_GOOD1_REG 0x08 /* Power Good1 Read */
|
||||
#define ALTR_A10SR_PWR_GOOD2_REG 0x0A /* Power Good2 Read */
|
||||
#define ALTR_A10SR_PWR_GOOD3_REG 0x0C /* Power Good3 Read */
|
||||
#define ALTR_A10SR_FMCAB_REG 0x0E /* FMCA/B & PCIe Pwr Enable */
|
||||
#define ALTR_A10SR_HPS_RST_REG 0x10 /* HPS Reset */
|
||||
#define ALTR_A10SR_USB_QSPI_REG 0x12 /* USB, BQSPI, FILE Reset */
|
||||
#define ALTR_A10SR_SFPA_REG 0x14 /* SFPA Control Reg */
|
||||
#define ALTR_A10SR_SFPB_REG 0x16 /* SFPB Control Reg */
|
||||
#define ALTR_A10SR_I2C_M_REG 0x18 /* I2C Master Select */
|
||||
#define ALTR_A10SR_WARM_RST_REG 0x1A /* HPS Warm Reset */
|
||||
#define ALTR_A10SR_WR_KEY_REG 0x1C /* HPS Warm Reset Key */
|
||||
#define ALTR_A10SR_PMBUS_REG 0x1E /* HPS PM Bus */
|
||||
|
||||
/**
|
||||
* struct altr_a10sr - Altera Max5 MFD device private data structure
|
||||
* @dev: : this device
|
||||
* @regmap: the regmap assigned to the parent device.
|
||||
*/
|
||||
struct altr_a10sr {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
#endif /* __MFD_ALTERA_A10SR_H */
|
@ -856,12 +856,6 @@
|
||||
#define ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE 0xB38
|
||||
#define ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE 0xB40
|
||||
#define ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE 0xB48
|
||||
#define ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE 0xB60
|
||||
#define ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE 0xB68
|
||||
#define ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE 0xB30
|
||||
#define ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE 0xB38
|
||||
#define ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE 0xB40
|
||||
#define ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE 0xB48
|
||||
#define ARIZONA_ISRC2DEC3MIX_INPUT_1_SOURCE 0xB50
|
||||
#define ARIZONA_ISRC2DEC4MIX_INPUT_1_SOURCE 0xB58
|
||||
#define ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE 0xB60
|
||||
|
@ -34,14 +34,23 @@
|
||||
#define PMU_VER_START 0x10
|
||||
#define PMU_VER_END 0x38
|
||||
|
||||
#define RESERVE_INT BIT(7)
|
||||
#define PWRON_D20R_INT BIT(6)
|
||||
#define PWRON_D20F_INT BIT(5)
|
||||
#define PWRON_D4SR_INT BIT(4)
|
||||
#define VSYS_6P0_D200UR_INT BIT(3)
|
||||
#define VSYS_UV_D3R_INT BIT(2)
|
||||
#define VSYS_2P5_R_INT BIT(1)
|
||||
#define OTMP_D1R_INT BIT(0)
|
||||
#define RESERVE_INT 7
|
||||
#define PWRON_D20R_INT 6
|
||||
#define PWRON_D20F_INT 5
|
||||
#define PWRON_D4SR_INT 4
|
||||
#define VSYS_6P0_D200UR_INT 3
|
||||
#define VSYS_UV_D3R_INT 2
|
||||
#define VSYS_2P5_R_INT 1
|
||||
#define OTMP_D1R_INT 0
|
||||
|
||||
#define RESERVE_INT_MASK BIT(RESERVE_INT)
|
||||
#define PWRON_D20R_INT_MASK BIT(PWRON_D20R_INT)
|
||||
#define PWRON_D20F_INT_MASK BIT(PWRON_D20F_INT)
|
||||
#define PWRON_D4SR_INT_MASK BIT(PWRON_D4SR_INT)
|
||||
#define VSYS_6P0_D200UR_INT_MASK BIT(VSYS_6P0_D200UR_INT)
|
||||
#define VSYS_UV_D3R_INT_MASK BIT(VSYS_UV_D3R_INT)
|
||||
#define VSYS_2P5_R_INT_MASK BIT(VSYS_2P5_R_INT)
|
||||
#define OTMP_D1R_INT_MASK BIT(OTMP_D1R_INT)
|
||||
|
||||
struct hi655x_pmic {
|
||||
struct resource *res;
|
||||
|
@ -62,6 +62,7 @@ enum {
|
||||
|
||||
struct stmpe_variant_info;
|
||||
struct stmpe_client_info;
|
||||
struct stmpe_platform_data;
|
||||
|
||||
/**
|
||||
* struct stmpe - STMPE MFD structure
|
||||
@ -117,25 +118,4 @@ extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks);
|
||||
|
||||
#define STMPE_GPIO_NOREQ_811_TOUCH (0xf0)
|
||||
|
||||
/**
|
||||
* struct stmpe_platform_data - STMPE platform data
|
||||
* @id: device id to distinguish between multiple STMPEs on the same board
|
||||
* @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*)
|
||||
* @irq_trigger: IRQ trigger to use for the interrupt to the host
|
||||
* @autosleep: bool to enable/disable stmpe autosleep
|
||||
* @autosleep_timeout: inactivity timeout in milliseconds for autosleep
|
||||
* @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)
|
||||
*/
|
||||
struct stmpe_platform_data {
|
||||
int id;
|
||||
unsigned int blocks;
|
||||
unsigned int irq_trigger;
|
||||
bool autosleep;
|
||||
bool irq_over_gpio;
|
||||
int irq_gpio;
|
||||
int autosleep_timeout;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -153,7 +153,7 @@
|
||||
|
||||
struct ti_tscadc_dev {
|
||||
struct device *dev;
|
||||
struct regmap *regmap_tscadc;
|
||||
struct regmap *regmap;
|
||||
void __iomem *tscadc_base;
|
||||
int irq;
|
||||
int used_cells; /* 1-2 */
|
||||
|
@ -226,6 +226,7 @@ struct twl6040 {
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
struct regulator_bulk_data supplies[2]; /* supplies for vio, v2v1 */
|
||||
struct clk *clk32k;
|
||||
struct clk *mclk;
|
||||
struct mutex mutex;
|
||||
struct mutex irq_mutex;
|
||||
struct mfd_cell cells[TWL6040_CELLS];
|
||||
@ -237,8 +238,8 @@ struct twl6040 {
|
||||
|
||||
/* PLL configuration */
|
||||
int pll;
|
||||
unsigned int sysclk;
|
||||
unsigned int mclk;
|
||||
unsigned int sysclk_rate;
|
||||
unsigned int mclk_rate;
|
||||
|
||||
unsigned int irq;
|
||||
unsigned int irq_ready;
|
||||
|
Loading…
Reference in New Issue
Block a user