mirror of
https://github.com/torvalds/linux.git
synced 2024-12-31 23:31:29 +00:00
Merge (most of) tag 'mfd-next-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "New Drivers: - Intel Cherry Trail Whiskey Cove PMIC - TI LP87565 PMIC New Device Support: - Add support for Cannonlake to intel-lpss-pci - Add support for Simatic IOT2000 to intel_quark_i2c_gpio New Functionality: - Add Regulator support (axp20x) Fix-ups: - Rework IRQ handling (intel_soc_pmic_bxtwc, rtsx_pcr, cros_ec) - Remove unused/unwelcome code (ipaq-micro, wm831x-core, da9062-core) - Provide deregistration on unbind (rn5t618) - Rework DT code/documentation (arizona) - Constify things (fsl-imx25-tsadc) - MAINTAINERS updates (DA9062/61) - Kconfig configuration adaptions (INTEL_SOC_PMIC, MFD_AXP20X_I2C) - Switch to DMI matching (intel_quark_i2c_gpio) - Provide an appropriate level of error checking (wm831x-{i2c,spi}, twl4030-irq, tc6393xb) - Make use of devm_* (resource handling) calls (intel_soc_pmic_bxtwc, stm32-timers, atmel-flexcom, cros_ec, fsl-imx25-tsadc, exynos-lpass, palmas, qcom-spmi-pmic, smsc-ece1099, motorola-cpcap)" [ Skipped the last commit in that series that added eight thousand lines of pointless repeated register definitions. - Linus ] * tag 'mfd-next-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (38 commits) mfd: Add LP87565 PMIC support mfd: cros_ec: Free IRQ on exit dt-bindings: vendor-prefixes: Add arctic to vendor prefix mfd: da9061: Fix to remove BBAT_CONT register from chip model mfd: da9061: Fix to remove BBAT_CONT register from chip model mfd: axp20x-i2c: Document that this must be builtin on x86 mfd: Add Cherry Trail Whiskey Cove PMIC driver mfd: tc6393xb: Handle return value of clk_prepare_enable mfd: intel_quark_i2c_gpio: Add support for SIMATIC IOT2000 platform mfd: intel_quark_i2c_gpio: Use dmi_system_id table for retrieving frequency mfd: motorola-cpcap: Use devm_of_platform_populate() mfd: smsc-ece: Use devm_of_platform_populate() mfd: qcom-spmi-pmic: Use devm_of_platform_populate() mfd: palmas: Use devm_of_platform_populate() mfd: exynos: Use devm_of_platform_populate() mfd: fsl-imx25: Use devm_of_platform_populate() mfd: cros_ec: Use devm_of_platform_populate() mfd: atmel: Use devm_of_platform_populate() mfd: stm32-timers: Use devm_of_platform_populate() mfd: intel_soc_pmic: Select designware i2c-bus driver ...
This commit is contained in:
commit
6972b007ca
@ -30,7 +30,8 @@ Required properties:
|
||||
|
||||
- gpio-controller : Indicates this device is a GPIO controller.
|
||||
- #gpio-cells : Must be 2. The first cell is the pin number and the
|
||||
second cell is used to specify optional parameters (currently unused).
|
||||
second cell is used to specify optional parameters, see ../gpio/gpio.txt
|
||||
for details.
|
||||
|
||||
- AVDD-supply, DBVDD1-supply, CPVDD-supply : Power supplies for the device,
|
||||
as covered in Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
43
Documentation/devicetree/bindings/mfd/lp87565.txt
Normal file
43
Documentation/devicetree/bindings/mfd/lp87565.txt
Normal file
@ -0,0 +1,43 @@
|
||||
TI LP87565 PMIC MFD driver
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,lp87565", "ti,lp87565-q1"
|
||||
- reg: I2C slave address.
|
||||
- gpio-controller: Marks the device node as a GPIO Controller.
|
||||
- #gpio-cells: Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify flags.
|
||||
See ../gpio/gpio.txt for more information.
|
||||
- xxx-in-supply: Phandle to parent supply node of each regulator
|
||||
populated under regulators node. xxx should match
|
||||
the supply_name populated in driver.
|
||||
Example:
|
||||
|
||||
lp87565_pmic: pmic@60 {
|
||||
compatible = "ti,lp87565-q1";
|
||||
reg = <0x60>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
buck10-in-supply = <&vsys_3v3>;
|
||||
buck23-in-supply = <&vsys_3v3>;
|
||||
|
||||
regulators: regulators {
|
||||
buck10_reg: buck10 {
|
||||
/* VDD_MPU */
|
||||
regulator-name = "buck10";
|
||||
regulator-min-microvolt = <850000>;
|
||||
regulator-max-microvolt = <1250000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
buck23_reg: buck23 {
|
||||
/* VDD_GPU */
|
||||
regulator-name = "buck23";
|
||||
regulator-min-microvolt = <850000>;
|
||||
regulator-max-microvolt = <1250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
@ -29,6 +29,7 @@ andestech Andes Technology Corporation
|
||||
apm Applied Micro Circuits Corporation (APM)
|
||||
aptina Aptina Imaging
|
||||
arasan Arasan Chip Systems
|
||||
arctic Arctic Sand
|
||||
aries Aries Embedded GmbH
|
||||
arm ARM Ltd.
|
||||
armadeus ARMadeus Systems SARL
|
||||
|
@ -4048,7 +4048,10 @@ W: http://www.dialog-semiconductor.com/products
|
||||
S: Supported
|
||||
F: Documentation/hwmon/da90??
|
||||
F: Documentation/devicetree/bindings/mfd/da90*.txt
|
||||
F: Documentation/devicetree/bindings/input/da90??-onkey.txt
|
||||
F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt
|
||||
F: Documentation/devicetree/bindings/regulator/da92*.txt
|
||||
F: Documentation/devicetree/bindings/watchdog/da92??-wdt.txt
|
||||
F: Documentation/devicetree/bindings/sound/da[79]*.txt
|
||||
F: drivers/gpio/gpio-da90??.c
|
||||
F: drivers/hwmon/da90??-hwmon.c
|
||||
@ -4063,6 +4066,7 @@ F: drivers/power/supply/da9052-battery.c
|
||||
F: drivers/power/supply/da91??-*.c
|
||||
F: drivers/regulator/da903x.c
|
||||
F: drivers/regulator/da9???-regulator.[ch]
|
||||
F: drivers/thermal/da90??-thermal.c
|
||||
F: drivers/rtc/rtc-da90??.c
|
||||
F: drivers/video/backlight/da90??_bl.c
|
||||
F: drivers/watchdog/da90??_wdt.c
|
||||
|
@ -428,7 +428,7 @@ static int wcove_gpio_probe(struct platform_device *pdev)
|
||||
if (!wg)
|
||||
return -ENOMEM;
|
||||
|
||||
wg->regmap_irq_chip = pmic->irq_chip_data_level2;
|
||||
wg->regmap_irq_chip = pmic->irq_chip_data;
|
||||
|
||||
platform_set_drvdata(pdev, wg);
|
||||
|
||||
@ -476,6 +476,18 @@ static int wcove_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
gpiochip_set_nested_irqchip(&wg->chip, &wcove_irqchip, virq);
|
||||
|
||||
/* Enable GPIO0 interrupts */
|
||||
ret = regmap_update_bits(wg->regmap, IRQ_MASK_BASE, GPIO_IRQ0_MASK,
|
||||
0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable GPIO1 interrupts */
|
||||
ret = regmap_update_bits(wg->regmap, IRQ_MASK_BASE + 1, GPIO_IRQ1_MASK,
|
||||
0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,11 @@ config MFD_AXP20X_I2C
|
||||
components like regulators or the PEK (Power Enable Key) under the
|
||||
corresponding menus.
|
||||
|
||||
Note on x86 this provides an ACPI OpRegion, so this must be 'y'
|
||||
(builtin) and not a module, as the OpRegion must be available as
|
||||
soon as possible. For the same reason the I2C bus driver options
|
||||
I2C_DESIGNWARE_PLATFORM and I2C_DESIGNWARE_BAYTRAIL must be 'y' too.
|
||||
|
||||
config MFD_AXP20X_RSB
|
||||
tristate "X-Powers AXP series PMICs with RSB"
|
||||
select MFD_AXP20X
|
||||
@ -448,17 +453,22 @@ config LPC_SCH
|
||||
|
||||
config INTEL_SOC_PMIC
|
||||
bool "Support for Crystal Cove PMIC"
|
||||
depends on GPIOLIB
|
||||
depends on I2C=y
|
||||
depends on HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK
|
||||
depends on X86 || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select I2C_DESIGNWARE_PLATFORM if ACPI
|
||||
help
|
||||
Select this option to enable support for Crystal Cove PMIC
|
||||
on some Intel SoC systems. The PMIC provides ADC, GPIO,
|
||||
thermal, charger and related power management functions
|
||||
on these systems.
|
||||
|
||||
This option is a bool as it provides an ACPI OpRegion which must be
|
||||
available before any devices using it are probed. This option also
|
||||
causes the designware-i2c driver to be builtin for the same reason.
|
||||
|
||||
config INTEL_SOC_PMIC_BXTWC
|
||||
tristate "Support for Intel Broxton Whiskey Cove PMIC"
|
||||
depends on INTEL_PMC_IPC
|
||||
@ -470,6 +480,22 @@ config INTEL_SOC_PMIC_BXTWC
|
||||
thermal, charger and related power management functions
|
||||
on these systems.
|
||||
|
||||
config INTEL_SOC_PMIC_CHTWC
|
||||
tristate "Support for Intel Cherry Trail Whiskey Cove PMIC"
|
||||
depends on ACPI && HAS_IOMEM && I2C=y && COMMON_CLK
|
||||
depends on X86 || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select I2C_DESIGNWARE_PLATFORM
|
||||
help
|
||||
Select this option to enable support for the Intel Cherry Trail
|
||||
Whiskey Cove PMIC found on some Intel Cherry Trail systems.
|
||||
|
||||
This option is a bool as it provides an ACPI OpRegion which must be
|
||||
available before any devices using it are probed. This option also
|
||||
causes the designware-i2c driver to be builtin for the same reason.
|
||||
|
||||
config MFD_INTEL_LPSS
|
||||
tristate
|
||||
select COMMON_CLK
|
||||
@ -1325,6 +1351,20 @@ config MFD_TI_LP873X
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called lp873x.
|
||||
|
||||
config MFD_TI_LP87565
|
||||
tristate "TI LP87565 Power Management IC"
|
||||
depends on I2C && OF
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
help
|
||||
If you say yes here then you get support for the LP87565 series of
|
||||
Power Management Integrated Circuits (PMIC).
|
||||
These include voltage regulators, thermal protection, configurable
|
||||
General Purpose Outputs (GPO) that are used in portable devices.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called lp87565.
|
||||
|
||||
config MFD_TPS65218
|
||||
tristate "TI TPS65218 Power Management chips"
|
||||
depends on I2C
|
||||
|
@ -25,6 +25,7 @@ obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
|
||||
obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
|
||||
|
||||
obj-$(CONFIG_MFD_TI_LP873X) += lp873x.o
|
||||
obj-$(CONFIG_MFD_TI_LP87565) += lp87565.o
|
||||
|
||||
obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
|
||||
obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
|
||||
@ -214,6 +215,7 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o
|
||||
intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
|
||||
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
|
||||
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
|
||||
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
|
||||
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
|
||||
|
||||
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
|
||||
|
@ -80,7 +80,7 @@ static int atmel_flexcom_probe(struct platform_device *pdev)
|
||||
|
||||
clk_disable_unprepare(clk);
|
||||
|
||||
return of_platform_populate(np, NULL, NULL, &pdev->dev);
|
||||
return devm_of_platform_populate(&pdev->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id atmel_flexcom_of_match[] = {
|
||||
|
@ -848,7 +848,8 @@ static struct mfd_cell axp803_cells[] = {
|
||||
.name = "axp20x-pek",
|
||||
.num_resources = ARRAY_SIZE(axp803_pek_resources),
|
||||
.resources = axp803_pek_resources,
|
||||
}
|
||||
},
|
||||
{ .name = "axp20x-regulator" },
|
||||
};
|
||||
|
||||
static struct mfd_cell axp806_cells[] = {
|
||||
|
@ -147,7 +147,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
|
||||
err = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
err = devm_of_platform_populate(dev);
|
||||
if (err) {
|
||||
mfd_remove_devices(dev);
|
||||
dev_err(dev, "Failed to register sub-devices\n");
|
||||
@ -183,6 +183,9 @@ int cros_ec_remove(struct cros_ec_device *ec_dev)
|
||||
|
||||
cros_ec_acpi_remove_gpe_handler();
|
||||
|
||||
if (ec_dev->irq)
|
||||
free_irq(ec_dev->irq, ec_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_remove);
|
||||
|
@ -428,9 +428,6 @@ static const struct regmap_range da9061_aa_readable_ranges[] = {
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_BBAT_CONT,
|
||||
.range_max = DA9062AA_BBAT_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_INTERFACE,
|
||||
.range_max = DA9062AA_CONFIG_E,
|
||||
@ -513,9 +510,6 @@ static const struct regmap_range da9061_aa_writeable_ranges[] = {
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_BBAT_CONT,
|
||||
.range_max = DA9062AA_BBAT_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_GP_ID_0,
|
||||
.range_max = DA9062AA_GP_ID_19,
|
||||
@ -650,9 +644,6 @@ static const struct regmap_range da9062_aa_readable_ranges[] = {
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_BBAT_CONT,
|
||||
.range_max = DA9062AA_BBAT_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_INTERFACE,
|
||||
.range_max = DA9062AA_CONFIG_E,
|
||||
@ -729,9 +720,6 @@ static const struct regmap_range da9062_aa_writeable_ranges[] = {
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_BBAT_CONT,
|
||||
.range_max = DA9062AA_BBAT_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_GP_ID_0,
|
||||
.range_max = DA9062AA_GP_ID_19,
|
||||
|
@ -138,7 +138,7 @@ static int exynos_lpass_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(dev);
|
||||
exynos_lpass_enable(lpass);
|
||||
|
||||
return of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
return devm_of_platform_populate(dev);
|
||||
}
|
||||
|
||||
static int exynos_lpass_remove(struct platform_device *pdev)
|
||||
|
@ -59,7 +59,7 @@ static int mx25_tsadc_domain_map(struct irq_domain *d, unsigned int irq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_domain_ops mx25_tsadc_domain_ops = {
|
||||
static const struct irq_domain_ops mx25_tsadc_domain_ops = {
|
||||
.map = mx25_tsadc_domain_map,
|
||||
.xlate = irq_domain_xlate_onecell,
|
||||
};
|
||||
@ -129,7 +129,6 @@ static void mx25_tsadc_setup_clk(struct platform_device *pdev,
|
||||
static int mx25_tsadc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct mx25_tsadc *tsadc;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
@ -178,9 +177,7 @@ static int mx25_tsadc_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, tsadc);
|
||||
|
||||
of_platform_populate(np, NULL, NULL, dev);
|
||||
|
||||
return 0;
|
||||
return devm_of_platform_populate(dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id mx25_tsadc_ids[] = {
|
||||
|
@ -201,6 +201,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d66), (kernel_ulong_t)&spt_uart_info },
|
||||
/* CNL-LP */
|
||||
{ PCI_VDEVICE(INTEL, 0x9da8), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9da9), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&spt_i2c_info },
|
||||
/* SPT-H */
|
||||
{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
|
||||
@ -219,6 +232,17 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa2e3), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa2e6), (kernel_ulong_t)&spt_uart_info },
|
||||
/* CNL-H */
|
||||
{ PCI_VDEVICE(INTEL, 0xa328), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa329), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa32a), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
|
||||
|
@ -58,19 +58,34 @@ struct intel_quark_mfd {
|
||||
struct clk_lookup *i2c_clk_lookup;
|
||||
};
|
||||
|
||||
struct i2c_mode_info {
|
||||
const char *name;
|
||||
unsigned int i2c_scl_freq;
|
||||
};
|
||||
|
||||
static const struct i2c_mode_info platform_i2c_mode_info[] = {
|
||||
static const struct dmi_system_id dmi_platform_info[] = {
|
||||
{
|
||||
.name = "Galileo",
|
||||
.i2c_scl_freq = 100000,
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
|
||||
},
|
||||
.driver_data = (void *)100000,
|
||||
},
|
||||
{
|
||||
.name = "GalileoGen2",
|
||||
.i2c_scl_freq = 400000,
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
|
||||
},
|
||||
.driver_data = (void *)400000,
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
|
||||
"6ES7647-0AA00-0YA2"),
|
||||
},
|
||||
.driver_data = (void *)400000,
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
|
||||
"6ES7647-0AA00-1YA2"),
|
||||
},
|
||||
.driver_data = (void *)400000,
|
||||
},
|
||||
{}
|
||||
};
|
||||
@ -160,8 +175,7 @@ static void intel_quark_unregister_i2c_clk(struct device *dev)
|
||||
|
||||
static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell)
|
||||
{
|
||||
const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
|
||||
const struct i2c_mode_info *info;
|
||||
const struct dmi_system_id *dmi_id;
|
||||
struct dw_i2c_platform_data *pdata;
|
||||
struct resource *res = (struct resource *)cell->resources;
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -181,14 +195,9 @@ static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell)
|
||||
/* Normal mode by default */
|
||||
pdata->i2c_scl_freq = 100000;
|
||||
|
||||
if (board_name) {
|
||||
for (info = platform_i2c_mode_info; info->name; info++) {
|
||||
if (!strcmp(board_name, info->name)) {
|
||||
pdata->i2c_scl_freq = info->i2c_scl_freq;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dmi_id = dmi_first_match(dmi_platform_info);
|
||||
if (dmi_id)
|
||||
pdata->i2c_scl_freq = (uintptr_t)dmi_id->driver_data;
|
||||
|
||||
cell->platform_data = pdata;
|
||||
cell->pdata_size = sizeof(*pdata);
|
||||
|
@ -82,20 +82,26 @@ enum bxtwc_irqs {
|
||||
BXTWC_PWRBTN_IRQ,
|
||||
};
|
||||
|
||||
enum bxtwc_irqs_level2 {
|
||||
/* Level 2 */
|
||||
BXTWC_THRM0_IRQ = 0,
|
||||
BXTWC_THRM1_IRQ,
|
||||
BXTWC_THRM2_IRQ,
|
||||
BXTWC_BCU_IRQ,
|
||||
BXTWC_ADC_IRQ,
|
||||
BXTWC_USBC_IRQ,
|
||||
enum bxtwc_irqs_bcu {
|
||||
BXTWC_BCU_IRQ = 0,
|
||||
};
|
||||
|
||||
enum bxtwc_irqs_adc {
|
||||
BXTWC_ADC_IRQ = 0,
|
||||
};
|
||||
|
||||
enum bxtwc_irqs_chgr {
|
||||
BXTWC_USBC_IRQ = 0,
|
||||
BXTWC_CHGR0_IRQ,
|
||||
BXTWC_CHGR1_IRQ,
|
||||
BXTWC_GPIO0_IRQ,
|
||||
BXTWC_GPIO1_IRQ,
|
||||
BXTWC_CRIT_IRQ,
|
||||
BXTWC_TMU_IRQ,
|
||||
};
|
||||
|
||||
enum bxtwc_irqs_tmu {
|
||||
BXTWC_TMU_IRQ = 0,
|
||||
};
|
||||
|
||||
enum bxtwc_irqs_crit {
|
||||
BXTWC_CRIT_IRQ = 0,
|
||||
};
|
||||
|
||||
static const struct regmap_irq bxtwc_regmap_irqs[] = {
|
||||
@ -110,24 +116,28 @@ static const struct regmap_irq bxtwc_regmap_irqs[] = {
|
||||
REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bxtwc_regmap_irqs_level2[] = {
|
||||
REGMAP_IRQ_REG(BXTWC_THRM0_IRQ, 0, 0xff),
|
||||
REGMAP_IRQ_REG(BXTWC_THRM1_IRQ, 1, 0xbf),
|
||||
REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
|
||||
REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
|
||||
REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
|
||||
REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 5, BIT(5)),
|
||||
REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
|
||||
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
|
||||
REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
|
||||
REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
|
||||
REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
|
||||
static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = {
|
||||
REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bxtwc_regmap_irqs_adc[] = {
|
||||
REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = {
|
||||
REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)),
|
||||
REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f),
|
||||
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = {
|
||||
REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bxtwc_regmap_irqs_crit[] = {
|
||||
REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03),
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
|
||||
.name = "bxtwc_irq_chip",
|
||||
.status_base = BXTWC_IRQLVL1,
|
||||
@ -137,15 +147,6 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
|
||||
.num_regs = 2,
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bxtwc_regmap_irq_chip_level2 = {
|
||||
.name = "bxtwc_irq_chip_level2",
|
||||
.status_base = BXTWC_THRM0IRQ,
|
||||
.mask_base = BXTWC_MTHRM0IRQ,
|
||||
.irqs = bxtwc_regmap_irqs_level2,
|
||||
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_level2),
|
||||
.num_regs = 10,
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {
|
||||
.name = "bxtwc_irq_chip_tmu",
|
||||
.status_base = BXTWC_TMUIRQ,
|
||||
@ -155,9 +156,44 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = {
|
||||
.name = "bxtwc_irq_chip_bcu",
|
||||
.status_base = BXTWC_BCUIRQ,
|
||||
.mask_base = BXTWC_MBCUIRQ,
|
||||
.irqs = bxtwc_regmap_irqs_bcu,
|
||||
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu),
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = {
|
||||
.name = "bxtwc_irq_chip_adc",
|
||||
.status_base = BXTWC_ADCIRQ,
|
||||
.mask_base = BXTWC_MADCIRQ,
|
||||
.irqs = bxtwc_regmap_irqs_adc,
|
||||
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc),
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = {
|
||||
.name = "bxtwc_irq_chip_chgr",
|
||||
.status_base = BXTWC_CHGR0IRQ,
|
||||
.mask_base = BXTWC_MCHGR0IRQ,
|
||||
.irqs = bxtwc_regmap_irqs_chgr,
|
||||
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr),
|
||||
.num_regs = 2,
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = {
|
||||
.name = "bxtwc_irq_chip_crit",
|
||||
.status_base = BXTWC_CRITIRQ,
|
||||
.mask_base = BXTWC_MCRITIRQ,
|
||||
.irqs = bxtwc_regmap_irqs_crit,
|
||||
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit),
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static struct resource gpio_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(BXTWC_GPIO0_IRQ, "GPIO0"),
|
||||
DEFINE_RES_IRQ_NAMED(BXTWC_GPIO1_IRQ, "GPIO1"),
|
||||
DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"),
|
||||
};
|
||||
|
||||
static struct resource adc_resources[] = {
|
||||
@ -174,9 +210,7 @@ static struct resource charger_resources[] = {
|
||||
};
|
||||
|
||||
static struct resource thermal_resources[] = {
|
||||
DEFINE_RES_IRQ(BXTWC_THRM0_IRQ),
|
||||
DEFINE_RES_IRQ(BXTWC_THRM1_IRQ),
|
||||
DEFINE_RES_IRQ(BXTWC_THRM2_IRQ),
|
||||
DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ),
|
||||
};
|
||||
|
||||
static struct resource bcu_resources[] = {
|
||||
@ -367,6 +401,26 @@ static const struct regmap_config bxtwc_regmap_config = {
|
||||
.reg_read = regmap_ipc_byte_reg_read,
|
||||
};
|
||||
|
||||
static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
|
||||
struct regmap_irq_chip_data *pdata,
|
||||
int pirq, int irq_flags,
|
||||
const struct regmap_irq_chip *chip,
|
||||
struct regmap_irq_chip_data **data)
|
||||
{
|
||||
int irq;
|
||||
|
||||
irq = regmap_irq_get_virq(pdata, pirq);
|
||||
if (irq < 0) {
|
||||
dev_err(pmic->dev,
|
||||
"Failed to get parent vIRQ(%d) for chip %s, ret:%d\n",
|
||||
pirq, chip->name, irq);
|
||||
return irq;
|
||||
}
|
||||
|
||||
return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags,
|
||||
0, chip, data);
|
||||
}
|
||||
|
||||
static int bxtwc_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
@ -409,45 +463,88 @@ static int bxtwc_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
0, &bxtwc_regmap_irq_chip,
|
||||
&pmic->irq_chip_data);
|
||||
ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
0, &bxtwc_regmap_irq_chip,
|
||||
&pmic->irq_chip_data);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add IRQ chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
0, &bxtwc_regmap_irq_chip_level2,
|
||||
&pmic->irq_chip_data_level2);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add secondary IRQ chip\n");
|
||||
goto err_irq_chip_level2;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
0, &bxtwc_regmap_irq_chip_tmu,
|
||||
&pmic->irq_chip_data_tmu);
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_TMU_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_tmu,
|
||||
&pmic->irq_chip_data_tmu);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n");
|
||||
goto err_irq_chip_tmu;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
|
||||
ARRAY_SIZE(bxt_wc_dev), NULL, 0,
|
||||
NULL);
|
||||
/* Add chained IRQ handler for BCU IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_BCU_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_bcu,
|
||||
&pmic->irq_chip_data_bcu);
|
||||
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add chained IRQ handler for ADC IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_ADC_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_adc,
|
||||
&pmic->irq_chip_data_adc);
|
||||
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add chained IRQ handler for CHGR IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_CHGR_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_chgr,
|
||||
&pmic->irq_chip_data_chgr);
|
||||
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add chained IRQ handler for CRIT IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_CRIT_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_crit,
|
||||
&pmic->irq_chip_data_crit);
|
||||
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
|
||||
ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add devices\n");
|
||||
goto err_mfd;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
|
||||
goto err_sysfs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -461,28 +558,11 @@ static int bxtwc_probe(struct platform_device *pdev)
|
||||
BXTWC_MIRQLVL1_MCHGR, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
err_sysfs:
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
err_mfd:
|
||||
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_tmu);
|
||||
err_irq_chip_tmu:
|
||||
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);
|
||||
err_irq_chip_level2:
|
||||
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bxtwc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
|
||||
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);
|
||||
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_tmu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
230
drivers/mfd/intel_soc_pmic_chtwc.c
Normal file
230
drivers/mfd/intel_soc_pmic_chtwc.c
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* MFD core driver for Intel Cherrytrail Whiskey Cove PMIC
|
||||
*
|
||||
* Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
|
||||
*
|
||||
* Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
|
||||
* Copyright (C) 2013-2015 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/intel_soc_pmic.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* PMIC device registers */
|
||||
#define REG_OFFSET_MASK GENMASK(7, 0)
|
||||
#define REG_ADDR_MASK GENMASK(15, 8)
|
||||
#define REG_ADDR_SHIFT 8
|
||||
|
||||
#define CHT_WC_IRQLVL1 0x6e02
|
||||
#define CHT_WC_IRQLVL1_MASK 0x6e0e
|
||||
|
||||
/* Whiskey Cove PMIC share same ACPI ID between different platforms */
|
||||
#define CHT_WC_HRV 3
|
||||
|
||||
/* Level 1 IRQs (level 2 IRQs are handled in the child device drivers) */
|
||||
enum {
|
||||
CHT_WC_PWRSRC_IRQ = 0,
|
||||
CHT_WC_THRM_IRQ,
|
||||
CHT_WC_BCU_IRQ,
|
||||
CHT_WC_ADC_IRQ,
|
||||
CHT_WC_EXT_CHGR_IRQ,
|
||||
CHT_WC_GPIO_IRQ,
|
||||
/* There is no irq 6 */
|
||||
CHT_WC_CRIT_IRQ = 7,
|
||||
};
|
||||
|
||||
static struct resource cht_wc_pwrsrc_resources[] = {
|
||||
DEFINE_RES_IRQ(CHT_WC_PWRSRC_IRQ),
|
||||
};
|
||||
|
||||
static struct resource cht_wc_ext_charger_resources[] = {
|
||||
DEFINE_RES_IRQ(CHT_WC_EXT_CHGR_IRQ),
|
||||
};
|
||||
|
||||
static struct mfd_cell cht_wc_dev[] = {
|
||||
{
|
||||
.name = "cht_wcove_pwrsrc",
|
||||
.num_resources = ARRAY_SIZE(cht_wc_pwrsrc_resources),
|
||||
.resources = cht_wc_pwrsrc_resources,
|
||||
}, {
|
||||
.name = "cht_wcove_ext_chgr",
|
||||
.num_resources = ARRAY_SIZE(cht_wc_ext_charger_resources),
|
||||
.resources = cht_wc_ext_charger_resources,
|
||||
},
|
||||
{ .name = "cht_wcove_region", },
|
||||
};
|
||||
|
||||
/*
|
||||
* The CHT Whiskey Cove covers multiple I2C addresses, with a 1 Byte
|
||||
* register address space per I2C address, so we use 16 bit register
|
||||
* addresses where the high 8 bits contain the I2C client address.
|
||||
*/
|
||||
static int cht_wc_byte_reg_read(void *context, unsigned int reg,
|
||||
unsigned int *val)
|
||||
{
|
||||
struct i2c_client *client = context;
|
||||
int ret, orig_addr = client->addr;
|
||||
|
||||
if (!(reg & REG_ADDR_MASK)) {
|
||||
dev_err(&client->dev, "Error I2C address not specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
client->addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
|
||||
ret = i2c_smbus_read_byte_data(client, reg & REG_OFFSET_MASK);
|
||||
client->addr = orig_addr;
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*val = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cht_wc_byte_reg_write(void *context, unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
struct i2c_client *client = context;
|
||||
int ret, orig_addr = client->addr;
|
||||
|
||||
if (!(reg & REG_ADDR_MASK)) {
|
||||
dev_err(&client->dev, "Error I2C address not specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
client->addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
|
||||
ret = i2c_smbus_write_byte_data(client, reg & REG_OFFSET_MASK, val);
|
||||
client->addr = orig_addr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct regmap_config cht_wc_regmap_cfg = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.reg_write = cht_wc_byte_reg_write,
|
||||
.reg_read = cht_wc_byte_reg_read,
|
||||
};
|
||||
|
||||
static const struct regmap_irq cht_wc_regmap_irqs[] = {
|
||||
REGMAP_IRQ_REG(CHT_WC_PWRSRC_IRQ, 0, BIT(CHT_WC_PWRSRC_IRQ)),
|
||||
REGMAP_IRQ_REG(CHT_WC_THRM_IRQ, 0, BIT(CHT_WC_THRM_IRQ)),
|
||||
REGMAP_IRQ_REG(CHT_WC_BCU_IRQ, 0, BIT(CHT_WC_BCU_IRQ)),
|
||||
REGMAP_IRQ_REG(CHT_WC_ADC_IRQ, 0, BIT(CHT_WC_ADC_IRQ)),
|
||||
REGMAP_IRQ_REG(CHT_WC_EXT_CHGR_IRQ, 0, BIT(CHT_WC_EXT_CHGR_IRQ)),
|
||||
REGMAP_IRQ_REG(CHT_WC_GPIO_IRQ, 0, BIT(CHT_WC_GPIO_IRQ)),
|
||||
REGMAP_IRQ_REG(CHT_WC_CRIT_IRQ, 0, BIT(CHT_WC_CRIT_IRQ)),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip cht_wc_regmap_irq_chip = {
|
||||
.name = "cht_wc_irq_chip",
|
||||
.status_base = CHT_WC_IRQLVL1,
|
||||
.mask_base = CHT_WC_IRQLVL1_MASK,
|
||||
.irqs = cht_wc_regmap_irqs,
|
||||
.num_irqs = ARRAY_SIZE(cht_wc_regmap_irqs),
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static int cht_wc_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct intel_soc_pmic *pmic;
|
||||
acpi_status status;
|
||||
unsigned long long hrv;
|
||||
int ret;
|
||||
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(dev, "Failed to get PMIC hardware revision\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (hrv != CHT_WC_HRV) {
|
||||
dev_err(dev, "Invalid PMIC hardware revision: %llu\n", hrv);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (client->irq < 0) {
|
||||
dev_err(dev, "Invalid IRQ\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
pmic->irq = client->irq;
|
||||
pmic->dev = dev;
|
||||
i2c_set_clientdata(client, pmic);
|
||||
|
||||
pmic->regmap = devm_regmap_init(dev, NULL, client, &cht_wc_regmap_cfg);
|
||||
if (IS_ERR(pmic->regmap))
|
||||
return PTR_ERR(pmic->regmap);
|
||||
|
||||
ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED, 0,
|
||||
&cht_wc_regmap_irq_chip,
|
||||
&pmic->irq_chip_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
cht_wc_dev, ARRAY_SIZE(cht_wc_dev), NULL, 0,
|
||||
regmap_irq_get_domain(pmic->irq_chip_data));
|
||||
}
|
||||
|
||||
static void cht_wc_shutdown(struct i2c_client *client)
|
||||
{
|
||||
struct intel_soc_pmic *pmic = i2c_get_clientdata(client);
|
||||
|
||||
disable_irq(pmic->irq);
|
||||
}
|
||||
|
||||
static int __maybe_unused cht_wc_suspend(struct device *dev)
|
||||
{
|
||||
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
|
||||
|
||||
disable_irq(pmic->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused cht_wc_resume(struct device *dev)
|
||||
{
|
||||
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
|
||||
|
||||
enable_irq(pmic->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static SIMPLE_DEV_PM_OPS(cht_wc_pm_ops, cht_wc_suspend, cht_wc_resume);
|
||||
|
||||
static const struct i2c_device_id cht_wc_i2c_id[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct acpi_device_id cht_wc_acpi_ids[] = {
|
||||
{ "INT34D3", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver cht_wc_driver = {
|
||||
.driver = {
|
||||
.name = "CHT Whiskey Cove PMIC",
|
||||
.pm = &cht_wc_pm_ops,
|
||||
.acpi_match_table = cht_wc_acpi_ids,
|
||||
},
|
||||
.probe_new = cht_wc_probe,
|
||||
.shutdown = cht_wc_shutdown,
|
||||
.id_table = cht_wc_i2c_id,
|
||||
};
|
||||
builtin_i2c_driver(cht_wc_driver);
|
@ -53,8 +53,6 @@ static void ipaq_micro_trigger_tx(struct ipaq_micro *micro)
|
||||
tx->buf[bp++] = checksum;
|
||||
tx->len = bp;
|
||||
tx->index = 0;
|
||||
print_hex_dump_debug("data: ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
tx->buf, tx->len, true);
|
||||
|
||||
/* Enable interrupt */
|
||||
val = readl(micro->base + UTCR3);
|
||||
@ -281,9 +279,6 @@ static void __init ipaq_micro_eeprom_dump(struct ipaq_micro *micro)
|
||||
dev_info(micro->dev, "RAM size: %u KiB\n", ipaq_micro_to_u16(dump+92));
|
||||
dev_info(micro->dev, "screen: %u x %u\n",
|
||||
ipaq_micro_to_u16(dump+94), ipaq_micro_to_u16(dump+96));
|
||||
print_hex_dump_debug("eeprom: ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
dump, 256, true);
|
||||
|
||||
}
|
||||
|
||||
static void micro_tx_chars(struct ipaq_micro *micro)
|
||||
|
100
drivers/mfd/lp87565.c
Normal file
100
drivers/mfd/lp87565.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Author: Keerthy <j-keerthy@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <linux/mfd/lp87565.h>
|
||||
|
||||
static const struct regmap_config lp87565_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = LP87565_REG_MAX,
|
||||
};
|
||||
|
||||
static const struct mfd_cell lp87565_cells[] = {
|
||||
{ .name = "lp87565-q1-regulator", },
|
||||
{ .name = "lp87565-q1-gpio", },
|
||||
};
|
||||
|
||||
static const struct of_device_id of_lp87565_match_table[] = {
|
||||
{ .compatible = "ti,lp87565", },
|
||||
{
|
||||
.compatible = "ti,lp87565-q1",
|
||||
.data = (void *)LP87565_DEVICE_TYPE_LP87565_Q1,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_lp87565_match_table);
|
||||
|
||||
static int lp87565_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *ids)
|
||||
{
|
||||
struct lp87565 *lp87565;
|
||||
const struct of_device_id *of_id;
|
||||
int ret;
|
||||
unsigned int otpid;
|
||||
|
||||
lp87565 = devm_kzalloc(&client->dev, sizeof(*lp87565), GFP_KERNEL);
|
||||
if (!lp87565)
|
||||
return -ENOMEM;
|
||||
|
||||
lp87565->dev = &client->dev;
|
||||
|
||||
lp87565->regmap = devm_regmap_init_i2c(client, &lp87565_regmap_config);
|
||||
if (IS_ERR(lp87565->regmap)) {
|
||||
ret = PTR_ERR(lp87565->regmap);
|
||||
dev_err(lp87565->dev,
|
||||
"Failed to initialize register map: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_read(lp87565->regmap, LP87565_REG_OTP_REV, &otpid);
|
||||
if (ret) {
|
||||
dev_err(lp87565->dev, "Failed to read OTP ID\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
lp87565->rev = otpid & LP87565_OTP_REV_OTP_ID;
|
||||
|
||||
of_id = of_match_device(of_lp87565_match_table, &client->dev);
|
||||
if (of_id)
|
||||
lp87565->dev_type = (enum lp87565_device_type)of_id->data;
|
||||
|
||||
i2c_set_clientdata(client, lp87565);
|
||||
|
||||
ret = mfd_add_devices(lp87565->dev, PLATFORM_DEVID_AUTO, lp87565_cells,
|
||||
ARRAY_SIZE(lp87565_cells), NULL, 0, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lp87565_id_table[] = {
|
||||
{ "lp87565-q1", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lp87565_id_table);
|
||||
|
||||
static struct i2c_driver lp87565_driver = {
|
||||
.driver = {
|
||||
.name = "lp87565",
|
||||
.of_match_table = of_lp87565_match_table,
|
||||
},
|
||||
.probe = lp87565_probe,
|
||||
.id_table = lp87565_id_table,
|
||||
};
|
||||
module_i2c_driver(lp87565_driver);
|
||||
|
||||
MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
|
||||
MODULE_DESCRIPTION("lp87565 chip family Multi-Function Device driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -260,17 +260,7 @@ static int cpcap_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return of_platform_populate(spi->dev.of_node, NULL, NULL,
|
||||
&cpcap->spi->dev);
|
||||
}
|
||||
|
||||
static int cpcap_remove(struct spi_device *pdev)
|
||||
{
|
||||
struct cpcap_ddata *cpcap = spi_get_drvdata(pdev);
|
||||
|
||||
of_platform_depopulate(&cpcap->spi->dev);
|
||||
|
||||
return 0;
|
||||
return devm_of_platform_populate(&cpcap->spi->dev);
|
||||
}
|
||||
|
||||
static struct spi_driver cpcap_driver = {
|
||||
@ -279,7 +269,6 @@ static struct spi_driver cpcap_driver = {
|
||||
.of_match_table = cpcap_of_match,
|
||||
},
|
||||
.probe = cpcap_probe,
|
||||
.remove = cpcap_remove,
|
||||
};
|
||||
module_spi_driver(cpcap_driver);
|
||||
|
||||
|
@ -676,7 +676,7 @@ no_irq:
|
||||
* otherwise continue and add devices using mfd helpers.
|
||||
*/
|
||||
if (node) {
|
||||
ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
|
||||
ret = devm_of_platform_populate(&i2c->dev);
|
||||
if (ret < 0) {
|
||||
goto err_irq;
|
||||
} else if (pdata->pm_off && !pm_power_off) {
|
||||
|
@ -120,7 +120,6 @@ static const struct regmap_config spmi_regmap_config = {
|
||||
|
||||
static int pmic_spmi_probe(struct spmi_device *sdev)
|
||||
{
|
||||
struct device_node *root = sdev->dev.of_node;
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config);
|
||||
@ -131,19 +130,13 @@ static int pmic_spmi_probe(struct spmi_device *sdev)
|
||||
if (sdev->usid % 2 == 0)
|
||||
pmic_spmi_show_revid(regmap, &sdev->dev);
|
||||
|
||||
return of_platform_populate(root, NULL, NULL, &sdev->dev);
|
||||
}
|
||||
|
||||
static void pmic_spmi_remove(struct spmi_device *sdev)
|
||||
{
|
||||
of_platform_depopulate(&sdev->dev);
|
||||
return devm_of_platform_populate(&sdev->dev);
|
||||
}
|
||||
|
||||
MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
|
||||
|
||||
static struct spmi_driver pmic_spmi_driver = {
|
||||
.probe = pmic_spmi_probe,
|
||||
.remove = pmic_spmi_remove,
|
||||
.driver = {
|
||||
.name = "pmic-spmi",
|
||||
.of_match_table = pmic_spmi_id_table,
|
||||
|
@ -155,6 +155,8 @@ static int rn5t618_i2c_remove(struct i2c_client *i2c)
|
||||
pm_power_off = NULL;
|
||||
}
|
||||
|
||||
unregister_restart_handler(&rn5t618_restart_handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/rtsx_pci.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "rtsx_pcr.h"
|
||||
@ -452,8 +453,12 @@ int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&pcr->lock, flags);
|
||||
if (pcr->trans_result == TRANS_RESULT_FAIL)
|
||||
err = -EINVAL;
|
||||
if (pcr->trans_result == TRANS_RESULT_FAIL) {
|
||||
err = -EILSEQ;
|
||||
if (pcr->dma_error_count < RTS_MAX_TIMES_FREQ_REDUCTION)
|
||||
pcr->dma_error_count++;
|
||||
}
|
||||
|
||||
else if (pcr->trans_result == TRANS_NO_DEVICE)
|
||||
err = -ENODEV;
|
||||
spin_unlock_irqrestore(&pcr->lock, flags);
|
||||
@ -659,6 +664,13 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Reduce card clock by 20MHz each time a DMA transfer error occurs */
|
||||
if (card_clock == UHS_SDR104_MAX_DTR &&
|
||||
pcr->dma_error_count &&
|
||||
PCI_PID(pcr) == RTS5227_DEVICE_ID)
|
||||
card_clock = UHS_SDR104_MAX_DTR -
|
||||
(pcr->dma_error_count * 20000000);
|
||||
|
||||
card_clock /= 1000000;
|
||||
pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock);
|
||||
|
||||
@ -894,6 +906,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
|
||||
pcr->card_removed |= SD_EXIST;
|
||||
pcr->card_inserted &= ~SD_EXIST;
|
||||
}
|
||||
pcr->dma_error_count = 0;
|
||||
}
|
||||
|
||||
if (int_reg & MS_INT) {
|
||||
|
@ -69,8 +69,7 @@ static int smsc_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
if (i2c->dev.of_node)
|
||||
ret = of_platform_populate(i2c->dev.of_node,
|
||||
NULL, NULL, &i2c->dev);
|
||||
ret = devm_of_platform_populate(&i2c->dev);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
@ -58,14 +58,7 @@ static int stm32_timers_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
|
||||
}
|
||||
|
||||
static int stm32_timers_remove(struct platform_device *pdev)
|
||||
{
|
||||
of_platform_depopulate(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
return devm_of_platform_populate(&pdev->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id stm32_timers_of_match[] = {
|
||||
@ -76,7 +69,6 @@ MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
|
||||
|
||||
static struct platform_driver stm32_timers_driver = {
|
||||
.probe = stm32_timers_probe,
|
||||
.remove = stm32_timers_remove,
|
||||
.driver = {
|
||||
.name = "stm32-timers",
|
||||
.of_match_table = stm32_timers_of_match,
|
||||
|
@ -797,7 +797,9 @@ static int tc6393xb_resume(struct platform_device *dev)
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
clk_prepare_enable(tc6393xb->clk);
|
||||
ret = clk_prepare_enable(tc6393xb->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = tcpd->resume(dev);
|
||||
if (ret)
|
||||
|
@ -638,8 +638,10 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
|
||||
}
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
if (status < 0) {
|
||||
dev_err(dev, "module to setup SIH for not found\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
agent = kzalloc(sizeof(*agent), GFP_KERNEL);
|
||||
if (!agent)
|
||||
|
@ -1766,7 +1766,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq)
|
||||
}
|
||||
wm831x->locked = 1;
|
||||
|
||||
if (pdata && pdata->pre_init) {
|
||||
if (pdata->pre_init) {
|
||||
ret = pdata->pre_init(wm831x);
|
||||
if (ret != 0) {
|
||||
dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
|
||||
@ -1774,19 +1774,17 @@ int wm831x_device_init(struct wm831x *wm831x, int irq)
|
||||
}
|
||||
}
|
||||
|
||||
if (pdata) {
|
||||
for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
|
||||
if (!pdata->gpio_defaults[i])
|
||||
continue;
|
||||
for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
|
||||
if (!pdata->gpio_defaults[i])
|
||||
continue;
|
||||
|
||||
wm831x_reg_write(wm831x,
|
||||
WM831X_GPIO1_CONTROL + i,
|
||||
pdata->gpio_defaults[i] & 0xffff);
|
||||
}
|
||||
wm831x_reg_write(wm831x,
|
||||
WM831X_GPIO1_CONTROL + i,
|
||||
pdata->gpio_defaults[i] & 0xffff);
|
||||
}
|
||||
|
||||
/* Multiply by 10 as we have many subdevices of the same type */
|
||||
if (pdata && pdata->wm831x_num)
|
||||
if (pdata->wm831x_num)
|
||||
wm831x_num = pdata->wm831x_num * 10;
|
||||
else
|
||||
wm831x_num = -1;
|
||||
@ -1809,7 +1807,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq)
|
||||
ret = mfd_add_devices(wm831x->dev, wm831x_num,
|
||||
wm8311_devs, ARRAY_SIZE(wm8311_devs),
|
||||
NULL, 0, NULL);
|
||||
if (!pdata || !pdata->disable_touch)
|
||||
if (!pdata->disable_touch)
|
||||
mfd_add_devices(wm831x->dev, wm831x_num,
|
||||
touch_devs, ARRAY_SIZE(touch_devs),
|
||||
NULL, 0, NULL);
|
||||
@ -1819,7 +1817,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq)
|
||||
ret = mfd_add_devices(wm831x->dev, wm831x_num,
|
||||
wm8312_devs, ARRAY_SIZE(wm8312_devs),
|
||||
NULL, 0, NULL);
|
||||
if (!pdata || !pdata->disable_touch)
|
||||
if (!pdata->disable_touch)
|
||||
mfd_add_devices(wm831x->dev, wm831x_num,
|
||||
touch_devs, ARRAY_SIZE(touch_devs),
|
||||
NULL, 0, NULL);
|
||||
@ -1865,7 +1863,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq)
|
||||
dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n");
|
||||
}
|
||||
|
||||
if (pdata && pdata->backlight) {
|
||||
if (pdata->backlight) {
|
||||
/* Treat errors as non-critical */
|
||||
ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
|
||||
ARRAY_SIZE(backlight_devs), NULL,
|
||||
@ -1877,7 +1875,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq)
|
||||
|
||||
wm831x_otp_init(wm831x);
|
||||
|
||||
if (pdata && pdata->post_init) {
|
||||
if (pdata->post_init) {
|
||||
ret = pdata->post_init(wm831x);
|
||||
if (ret != 0) {
|
||||
dev_err(wm831x->dev, "post_init() failed: %d\n", ret);
|
||||
|
@ -37,6 +37,10 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
if (i2c->dev.of_node) {
|
||||
of_id = of_match_device(wm831x_of_match, &i2c->dev);
|
||||
if (!of_id) {
|
||||
dev_err(&i2c->dev, "Failed to match device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
type = (enum wm831x_parent)of_id->data;
|
||||
} else {
|
||||
type = (enum wm831x_parent)id->driver_data;
|
||||
|
@ -34,6 +34,10 @@ static int wm831x_spi_probe(struct spi_device *spi)
|
||||
|
||||
if (spi->dev.of_node) {
|
||||
of_id = of_match_device(wm831x_of_match, &spi->dev);
|
||||
if (!of_id) {
|
||||
dev_err(&spi->dev, "Failed to match device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
type = (enum wm831x_parent)of_id->data;
|
||||
} else {
|
||||
type = (enum wm831x_parent)id->driver_data;
|
||||
|
@ -92,10 +92,6 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
|
||||
}
|
||||
wctmu->irq = virq;
|
||||
|
||||
/* Enable TMU interrupts */
|
||||
regmap_update_bits(wctmu->regmap, BXTWC_MIRQLVL1,
|
||||
BXTWC_MIRQLVL1_MTMU, 0);
|
||||
|
||||
/* Unmask TMU second level Wake & System alarm */
|
||||
regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG,
|
||||
BXTWC_TMU_ALRM_MASK, 0);
|
||||
|
@ -241,7 +241,7 @@ static int pmic_thermal_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
regmap = pmic->regmap;
|
||||
regmap_irq_chip = pmic->irq_chip_data_level2;
|
||||
regmap_irq_chip = pmic->irq_chip_data;
|
||||
|
||||
pmic_irq_count = 0;
|
||||
while ((irq = platform_get_irq(pdev, pmic_irq_count)) != -ENXIO) {
|
||||
|
@ -303,7 +303,7 @@ static int wcove_typec_probe(struct platform_device *pdev)
|
||||
wcove->dev = &pdev->dev;
|
||||
wcove->regmap = pmic->regmap;
|
||||
|
||||
ret = regmap_irq_get_virq(pmic->irq_chip_data_level2,
|
||||
ret = regmap_irq_get_virq(pmic->irq_chip_data_chgr,
|
||||
platform_get_irq(pdev, 0));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -25,8 +25,11 @@ struct intel_soc_pmic {
|
||||
int irq;
|
||||
struct regmap *regmap;
|
||||
struct regmap_irq_chip_data *irq_chip_data;
|
||||
struct regmap_irq_chip_data *irq_chip_data_level2;
|
||||
struct regmap_irq_chip_data *irq_chip_data_tmu;
|
||||
struct regmap_irq_chip_data *irq_chip_data_bcu;
|
||||
struct regmap_irq_chip_data *irq_chip_data_adc;
|
||||
struct regmap_irq_chip_data *irq_chip_data_chgr;
|
||||
struct regmap_irq_chip_data *irq_chip_data_crit;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
|
270
include/linux/mfd/lp87565.h
Normal file
270
include/linux/mfd/lp87565.h
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Functions to access LP87565 power management chip.
|
||||
*
|
||||
* Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_LP87565_H
|
||||
#define __LINUX_MFD_LP87565_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
enum lp87565_device_type {
|
||||
LP87565_DEVICE_TYPE_UNKNOWN = 0,
|
||||
LP87565_DEVICE_TYPE_LP87565_Q1,
|
||||
};
|
||||
|
||||
/* All register addresses */
|
||||
#define LP87565_REG_DEV_REV 0X00
|
||||
#define LP87565_REG_OTP_REV 0X01
|
||||
#define LP87565_REG_BUCK0_CTRL_1 0X02
|
||||
#define LP87565_REG_BUCK0_CTRL_2 0X03
|
||||
|
||||
#define LP87565_REG_BUCK1_CTRL_1 0X04
|
||||
#define LP87565_REG_BUCK1_CTRL_2 0X05
|
||||
|
||||
#define LP87565_REG_BUCK2_CTRL_1 0X06
|
||||
#define LP87565_REG_BUCK2_CTRL_2 0X07
|
||||
|
||||
#define LP87565_REG_BUCK3_CTRL_1 0X08
|
||||
#define LP87565_REG_BUCK3_CTRL_2 0X09
|
||||
|
||||
#define LP87565_REG_BUCK0_VOUT 0X0A
|
||||
#define LP87565_REG_BUCK0_FLOOR_VOUT 0X0B
|
||||
|
||||
#define LP87565_REG_BUCK1_VOUT 0X0C
|
||||
#define LP87565_REG_BUCK1_FLOOR_VOUT 0X0D
|
||||
|
||||
#define LP87565_REG_BUCK2_VOUT 0X0E
|
||||
#define LP87565_REG_BUCK2_FLOOR_VOUT 0X0F
|
||||
|
||||
#define LP87565_REG_BUCK3_VOUT 0X10
|
||||
#define LP87565_REG_BUCK3_FLOOR_VOUT 0X11
|
||||
|
||||
#define LP87565_REG_BUCK0_DELAY 0X12
|
||||
#define LP87565_REG_BUCK1_DELAY 0X13
|
||||
|
||||
#define LP87565_REG_BUCK2_DELAY 0X14
|
||||
#define LP87565_REG_BUCK3_DELAY 0X15
|
||||
|
||||
#define LP87565_REG_GPO2_DELAY 0X16
|
||||
#define LP87565_REG_GPO3_DELAY 0X17
|
||||
#define LP87565_REG_RESET 0X18
|
||||
#define LP87565_REG_CONFIG 0X19
|
||||
|
||||
#define LP87565_REG_INT_TOP_1 0X1A
|
||||
#define LP87565_REG_INT_TOP_2 0X1B
|
||||
|
||||
#define LP87565_REG_INT_BUCK_0_1 0X1C
|
||||
#define LP87565_REG_INT_BUCK_2_3 0X1D
|
||||
#define LP87565_REG_TOP_STAT 0X1E
|
||||
#define LP87565_REG_BUCK_0_1_STAT 0X1F
|
||||
#define LP87565_REG_BUCK_2_3_STAT 0x20
|
||||
|
||||
#define LP87565_REG_TOP_MASK_1 0x21
|
||||
#define LP87565_REG_TOP_MASK_2 0x22
|
||||
|
||||
#define LP87565_REG_BUCK_0_1_MASK 0x23
|
||||
#define LP87565_REG_BUCK_2_3_MASK 0x24
|
||||
#define LP87565_REG_SEL_I_LOAD 0x25
|
||||
|
||||
#define LP87565_REG_I_LOAD_2 0x26
|
||||
#define LP87565_REG_I_LOAD_1 0x27
|
||||
|
||||
#define LP87565_REG_PGOOD_CTRL1 0x28
|
||||
#define LP87565_REG_PGOOD_CTRL2 0x29
|
||||
#define LP87565_REG_PGOOD_FLT 0x2A
|
||||
#define LP87565_REG_PLL_CTRL 0x2B
|
||||
#define LP87565_REG_PIN_FUNCTION 0x2C
|
||||
#define LP87565_REG_GPIO_CONFIG 0x2D
|
||||
#define LP87565_REG_GPIO_IN 0x2E
|
||||
#define LP87565_REG_GPIO_OUT 0x2F
|
||||
|
||||
#define LP87565_REG_MAX LP87565_REG_GPIO_OUT
|
||||
|
||||
/* Register field definitions */
|
||||
#define LP87565_DEV_REV_DEV_ID 0xC0
|
||||
#define LP87565_DEV_REV_ALL_LAYER 0x30
|
||||
#define LP87565_DEV_REV_METAL_LAYER 0x0F
|
||||
|
||||
#define LP87565_OTP_REV_OTP_ID 0xFF
|
||||
|
||||
#define LP87565_BUCK_CTRL_1_EN BIT(7)
|
||||
#define LP87565_BUCK_CTRL_1_EN_PIN_CTRL BIT(6)
|
||||
#define LP87565_BUCK_CTRL_1_PIN_SELECT_EN 0x30
|
||||
|
||||
#define LP87565_BUCK_CTRL_1_ROOF_FLOOR_EN BIT(3)
|
||||
#define LP87565_BUCK_CTRL_1_RDIS_EN BIT(2)
|
||||
#define LP87565_BUCK_CTRL_1_FPWM BIT(1)
|
||||
/* Bit0 is reserved for BUCK1 and BUCK3 and valid only for BUCK0 and BUCK2 */
|
||||
#define LP87565_BUCK_CTRL_1_FPWM_MP_0_2 BIT(0)
|
||||
|
||||
#define LP87565_BUCK_CTRL_2_ILIM 0x38
|
||||
#define LP87565_BUCK_CTRL_2_SLEW_RATE 0x07
|
||||
|
||||
#define LP87565_BUCK_VSET 0xFF
|
||||
#define LP87565_BUCK_FLOOR_VSET 0xFF
|
||||
|
||||
#define LP87565_BUCK_SHUTDOWN_DELAY 0xF0
|
||||
#define LP87565_BUCK_STARTUP_DELAY 0x0F
|
||||
|
||||
#define LP87565_GPIO_SHUTDOWN_DELAY 0xF0
|
||||
#define LP87565_GPIO_STARTUP_DELAY 0x0F
|
||||
|
||||
#define LP87565_RESET_SW_RESET BIT(0)
|
||||
|
||||
#define LP87565_CONFIG_DOUBLE_DELAY BIT(7)
|
||||
#define LP87565_CONFIG_CLKIN_PD BIT(6)
|
||||
#define LP87565_CONFIG_EN4_PD BIT(5)
|
||||
#define LP87565_CONFIG_EN3_PD BIT(4)
|
||||
#define LP87565_CONFIG_TDIE_WARN_LEVEL BIT(3)
|
||||
#define LP87565_CONFIG_EN2_PD BIT(2)
|
||||
#define LP87565_CONFIG_EN1_PD BIT(1)
|
||||
|
||||
#define LP87565_INT_GPIO BIT(7)
|
||||
#define LP87565_INT_BUCK23 BIT(6)
|
||||
#define LP87565_INT_BUCK01 BIT(5)
|
||||
#define LP87565_NO_SYNC_CLK BIT(4)
|
||||
#define LP87565_TDIE_SD BIT(3)
|
||||
#define LP87565_TDIE_WARN BIT(2)
|
||||
#define LP87565_INT_OVP BIT(1)
|
||||
#define LP87565_I_LOAD_READY BIT(0)
|
||||
|
||||
#define LP87565_INT_TOP2_RESET_REG BIT(0)
|
||||
|
||||
#define LP87565_BUCK1_PG_INT BIT(6)
|
||||
#define LP87565_BUCK1_SC_INT BIT(5)
|
||||
#define LP87565_BUCK1_ILIM_INT BIT(4)
|
||||
#define LP87565_BUCK0_PG_INT BIT(2)
|
||||
#define LP87565_BUCK0_SC_INT BIT(1)
|
||||
#define LP87565_BUCK0_ILIM_INT BIT(0)
|
||||
|
||||
#define LP87565_BUCK3_PG_INT BIT(6)
|
||||
#define LP87565_BUCK3_SC_INT BIT(5)
|
||||
#define LP87565_BUCK3_ILIM_INT BIT(4)
|
||||
#define LP87565_BUCK2_PG_INT BIT(2)
|
||||
#define LP87565_BUCK2_SC_INT BIT(1)
|
||||
#define LP87565_BUCK2_ILIM_INT BIT(0)
|
||||
|
||||
#define LP87565_SYNC_CLK_STAT BIT(4)
|
||||
#define LP87565_TDIE_SD_STAT BIT(3)
|
||||
#define LP87565_TDIE_WARN_STAT BIT(2)
|
||||
#define LP87565_OVP_STAT BIT(1)
|
||||
|
||||
#define LP87565_BUCK1_STAT BIT(7)
|
||||
#define LP87565_BUCK1_PG_STAT BIT(6)
|
||||
#define LP87565_BUCK1_ILIM_STAT BIT(4)
|
||||
#define LP87565_BUCK0_STAT BIT(3)
|
||||
#define LP87565_BUCK0_PG_STAT BIT(2)
|
||||
#define LP87565_BUCK0_ILIM_STAT BIT(0)
|
||||
|
||||
#define LP87565_BUCK3_STAT BIT(7)
|
||||
#define LP87565_BUCK3_PG_STAT BIT(6)
|
||||
#define LP87565_BUCK3_ILIM_STAT BIT(4)
|
||||
#define LP87565_BUCK2_STAT BIT(3)
|
||||
#define LP87565_BUCK2_PG_STAT BIT(2)
|
||||
#define LP87565_BUCK2_ILIM_STAT BIT(0)
|
||||
|
||||
#define LPL87565_GPIO_MASK BIT(7)
|
||||
#define LPL87565_SYNC_CLK_MASK BIT(4)
|
||||
#define LPL87565_TDIE_WARN_MASK BIT(2)
|
||||
#define LPL87565_I_LOAD_READY_MASK BIT(0)
|
||||
|
||||
#define LPL87565_RESET_REG_MASK BIT(0)
|
||||
|
||||
#define LPL87565_BUCK1_PG_MASK BIT(6)
|
||||
#define LPL87565_BUCK1_ILIM_MASK BIT(4)
|
||||
#define LPL87565_BUCK0_PG_MASK BIT(2)
|
||||
#define LPL87565_BUCK0_ILIM_MASK BIT(0)
|
||||
|
||||
#define LPL87565_BUCK3_PG_MASK BIT(6)
|
||||
#define LPL87565_BUCK3_ILIM_MASK BIT(4)
|
||||
#define LPL87565_BUCK2_PG_MASK BIT(2)
|
||||
#define LPL87565_BUCK2_ILIM_MASK BIT(0)
|
||||
|
||||
#define LP87565_LOAD_CURRENT_BUCK_SELECT 0x3
|
||||
|
||||
#define LP87565_I_LOAD2_BUCK_LOAD_CURRENT 0x3
|
||||
#define LP87565_I_LOAD1_BUCK_LOAD_CURRENT 0xFF
|
||||
|
||||
#define LP87565_PG3_SEL 0xC0
|
||||
#define LP87565_PG2_SEL 0x30
|
||||
#define LP87565_PG1_SEL 0x0C
|
||||
#define LP87565_PG0_SEL 0x03
|
||||
|
||||
#define LP87565_HALF_DAY BIT(7)
|
||||
#define LP87565_EN_PG0_NINT BIT(6)
|
||||
#define LP87565_PGOOD_SET_DELAY BIT(5)
|
||||
#define LP87565_EN_PGFLT_STAT BIT(4)
|
||||
#define LP87565_PGOOD_WINDOW BIT(2)
|
||||
#define LP87565_PGOOD_OD BIT(1)
|
||||
#define LP87565_PGOOD_POL BIT(0)
|
||||
|
||||
#define LP87565_PG3_FLT BIT(3)
|
||||
#define LP87565_PG2_FLT BIT(2)
|
||||
#define LP87565_PG1_FLT BIT(1)
|
||||
#define LP87565_PG0_FLT BIT(0)
|
||||
|
||||
#define LP87565_PLL_MODE 0xC0
|
||||
#define LP87565_EXT_CLK_FREQ 0x1F
|
||||
|
||||
#define LP87565_EN_SPREAD_SPEC BIT(7)
|
||||
#define LP87565_EN_PIN_CTRL_GPIO3 BIT(6)
|
||||
#define LP87565_EN_PIN_SELECT_GPIO3 BIT(5)
|
||||
#define LP87565_EN_PIN_CTRL_GPIO2 BIT(4)
|
||||
#define LP87565_EN_PIN_SELECT_GPIO2 BIT(3)
|
||||
#define LP87565_GPIO3_SEL BIT(2)
|
||||
#define LP87565_GPIO2_SEL BIT(1)
|
||||
#define LP87565_GPIO1_SEL BIT(0)
|
||||
|
||||
#define LP87565_GOIO3_OD BIT(6)
|
||||
#define LP87565_GOIO2_OD BIT(5)
|
||||
#define LP87565_GOIO1_OD BIT(4)
|
||||
#define LP87565_GOIO3_DIR BIT(2)
|
||||
#define LP87565_GOIO2_DIR BIT(1)
|
||||
#define LP87565_GOIO1_DIR BIT(0)
|
||||
|
||||
#define LP87565_GOIO3_IN BIT(2)
|
||||
#define LP87565_GOIO2_IN BIT(1)
|
||||
#define LP87565_GOIO1_IN BIT(0)
|
||||
|
||||
#define LP87565_GOIO3_OUT BIT(2)
|
||||
#define LP87565_GOIO2_OUT BIT(1)
|
||||
#define LP87565_GOIO1_OUT BIT(0)
|
||||
|
||||
/* Number of step-down converters available */
|
||||
#define LP87565_NUM_BUCK 6
|
||||
|
||||
enum LP87565_regulator_id {
|
||||
/* BUCK's */
|
||||
LP87565_BUCK_0,
|
||||
LP87565_BUCK_1,
|
||||
LP87565_BUCK_2,
|
||||
LP87565_BUCK_3,
|
||||
LP87565_BUCK_10,
|
||||
LP87565_BUCK_23,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct LP87565 - state holder for the LP87565 driver
|
||||
* @dev: struct device pointer for MFD device
|
||||
* @rev: revision of the LP87565
|
||||
* @dev_type: The device type for example lp87565-q1
|
||||
* @lock: lock guarding the data structure
|
||||
* @regmap: register map of the LP87565 PMIC
|
||||
*
|
||||
* Device data may be used to access the LP87565 chip
|
||||
*/
|
||||
struct lp87565 {
|
||||
struct device *dev;
|
||||
u8 rev;
|
||||
u8 dev_type;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
#endif /* __LINUX_MFD_LP87565_H */
|
@ -850,6 +850,9 @@
|
||||
|
||||
#define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0)
|
||||
|
||||
#define RTS5227_DEVICE_ID 0x5227
|
||||
#define RTS_MAX_TIMES_FREQ_REDUCTION 8
|
||||
|
||||
struct rtsx_pcr;
|
||||
|
||||
struct pcr_handle {
|
||||
@ -957,6 +960,8 @@ struct rtsx_pcr {
|
||||
|
||||
int num_slots;
|
||||
struct rtsx_slot *slots;
|
||||
|
||||
u8 dma_error_count;
|
||||
};
|
||||
|
||||
#define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))
|
||||
|
Loading…
Reference in New Issue
Block a user