mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
- New Device Support
- Add support for Ricoh RC5T619 PMIC to rn5t618 - Add support for PM8821 PMIC to qcom-pm8xxx - New Functionality - Add support for GPIO to lpc_ich - Add support for GPADC to sun4i - Add ability for rk808 to shutdown - Fix-ups - Simplify/strip unnecessary code; tps65218, palmas, tps65217 - Device Tree binding updates; tps65218, altera-a10sr - Provide/export device ID info; tps65218, axp20x-i2c, hi655x-pmic, fsl-imx25-tsadc, intel_soc_pmic_bxtwc - Use MFD API instead of of_platform_populate(); tps65218 - Generalise name-space; pm8xxx - Supply/edit regmap configuration; axp20x, cs47l24-tables, axp20x - Enable compile testing; max77620, max77686, exynos-lpass, abx500-core - Coding style issues; wm8994-core, wm5102-tables - Supply endian support; syscon - Remove module support; ab3100-core, ab8500-debugfs, ab8500-gpadc, abx500-core - Bug Fixes - Fix ordering issues; wm8994 - Fix dependencies (build-time/run-time); exynos_lpass, sun4i-gpadc - Fix compiler warnings; sun4i-gpadc - Fix leaks; mfd-core - Fix page fault during module unload; tps65217 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAlhXxxcACgkQUa+KL4f8 d2HDnxAAhYdrm6+4jYUDzXpKuKPDO4GNakvXY2aTk8dHobca8ySLcDZZ1s0KLLWa iOgOGmVQjL04vraiHiqGYW8kPONeslgFqhhqHmVvMZtLka3ZRXb9BWE6mLa7JBDg LONQFfpiDlbBChiuDSqBKYj0p0Wp65uFF/jtJxGTXe+vUTO94Lbrgo6tCmuAgBf/ k2JS4+/Ufa3QuXuvPm8cVleWhhyEqkWGLJqv5PaDxjNQwP78PzXMYvfOEcCyUpNR hUoG2xJl+aPilVr0I9rsWIqgmDgRHlX67oMneoZkMiVQj20+Yi8YojDgGOpcaOZX Oh/YpdAEqaZh98EX5dKnuM8NQERltl/fTDpe3JNTPl42QYLMDzyBBb810xNzrB7W irJLzmfjEsPH7oYA63/EU3an6yXGXcB1lZ8wTPqFXOpGqw2/3SDSlTjonTxW1nnX yUXVV3VUS0xlHg0GHDuCbUvkJQSi2W6x/A/mzL8QBaKO7iUzv0P/oTZIZZe4Y06f LUCx4vb6W9i+9Me/z1aieXgXqC842U66OTmz1AmNRcntFspAeR3Rg3wGLP6+L/A+ 51Lumjn1IsHwgyd+/uQ3vsb35W/ZNYxTuc61HbWRPSX984sIdtI2+DL4+c8WBPLw MQgTy6ULb5bCt2HQ6DbwMZRpM6hIY2ed/QnJN2q2c3VBA1YgzzQ= =Lkoz -----END PGP SIGNATURE----- Merge tag 'mfd-for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Device Support - Add support for Ricoh RC5T619 PMIC to rn5t618 - Add support for PM8821 PMIC to qcom-pm8xxx New Functionality: - Add support for GPIO to lpc_ich - Add support for GPADC to sun4i - Add ability for rk808 to shutdown Fix-ups: - Simplify/strip unnecessary code; tps65218, palmas, tps65217 - Device Tree binding updates; tps65218, altera-a10sr - Provide/export device ID info; tps65218, axp20x-i2c, hi655x-pmic, fsl-imx25-tsadc, intel_soc_pmic_bxtwc - Use MFD API instead of of_platform_populate(); tps65218 - Generalise name-space; pm8xxx - Supply/edit regmap configuration; axp20x, cs47l24-tables, axp20x - Enable compile testing; max77620, max77686, exynos-lpass, abx500-core - Coding style issues; wm8994-core, wm5102-tables - Supply endian support; syscon - Remove module support; ab3100-core, ab8500-debugfs, ab8500-gpadc, abx500-core Bug Fixes: - Fix ordering issues; wm8994 - Fix dependencies (build-time/run-time); exynos_lpass, sun4i-gpadc - Fix compiler warnings; sun4i-gpadc - Fix leaks; mfd-core - Fix page fault during module unload; tps65217" * tag 'mfd-for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (49 commits) mfd: tps65217: Support an interrupt pin as the system wakeup mfd: tps65217: Make an interrupt handler simpler mfd: tps65217: Update register interrupt mask bits instead of writing operation mfd: tps65217: Specify the IRQ name mfd: tps65217: Fix page fault on unloading modules mfd: palmas: Remove redundant check in palmas_power_off mfd: arizona: Disable IRQs during driver remove mfd: pm8xxx: add support to pm8821 mfd: intel-lpss: Try to enable Memory-Write-Invalidate mfd: rn5t618: Add Ricoh RC5T619 PMIC support mfd: axp20x: Add address extension registers for AXP806 regmap mfd: intel_soc_pmic_bxtwc: Fix a typo in MODULE_DEVICE_TABLE() mfd: core: Fix device reference leak in mfd_clone_cell mfd: bcm590xx: Simplify a test mfd: sun4i-gpadc: Select regmap-irq mfd: abx500-core: drop unused MODULE_ tags from non-modular code mfd: ab8500: make sysctrl explicitly non-modular mfd: ab8500-gpadc: Make it explicitly non-modular mfd: ab8500-debugfs: Make it explicitly non-modular mfd: ab8500-core: Make it explicitly non-modular ...
This commit is contained in:
commit
ac5a28b0d3
46
Documentation/devicetree/bindings/mfd/altera-a10sr.txt
Normal file
46
Documentation/devicetree/bindings/mfd/altera-a10sr.txt
Normal file
@ -0,0 +1,46 @@
|
||||
* Altera Arria10 Development Kit System Resource Chip
|
||||
|
||||
Required parent device properties:
|
||||
- compatible : "altr,a10sr"
|
||||
- spi-max-frequency : Maximum SPI frequency.
|
||||
- reg : The SPI Chip Select address for the Arria10
|
||||
System Resource chip
|
||||
- interrupt-parent : The parent interrupt controller.
|
||||
- interrupts : The interrupt line the device is connected to.
|
||||
- interrupt-controller : Marks the device node as an interrupt controller.
|
||||
- #interrupt-cells : The number of cells to describe an IRQ, should be 2.
|
||||
The first cell is the IRQ number.
|
||||
The second cell is the flags, encoded as trigger
|
||||
masks from ../interrupt-controller/interrupts.txt.
|
||||
|
||||
The A10SR consists of these sub-devices:
|
||||
|
||||
Device Description
|
||||
------ ----------
|
||||
a10sr_gpio GPIO Controller
|
||||
|
||||
Arria10 GPIO
|
||||
Required Properties:
|
||||
- compatible : Should be "altr,a10sr-gpio"
|
||||
- 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.
|
||||
|
||||
Example:
|
||||
|
||||
resource-manager@0 {
|
||||
compatible = "altr,a10sr";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000>;
|
||||
interrupt-parent = <&portb>;
|
||||
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
a10sr_gpio: gpio-controller {
|
||||
compatible = "altr,a10sr-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
@ -10,6 +10,7 @@ voltages and other various functionality to Qualcomm SoCs.
|
||||
Value type: <string>
|
||||
Definition: must be one of:
|
||||
"qcom,pm8058"
|
||||
"qcom,pm8821"
|
||||
"qcom,pm8921"
|
||||
|
||||
- #address-cells:
|
||||
|
@ -1,21 +1,25 @@
|
||||
* Ricoh RN5T567/RN5T618 PMIC
|
||||
|
||||
Ricoh RN5T567/RN5T618 is a power management IC family which integrates
|
||||
3 to 4 step-down DCDC converters, 7 low-dropout regulators, GPIOs and
|
||||
a watchdog timer. The RN5T618 provides additionally a Li-ion battery
|
||||
charger, fuel gauge and an ADC. It can be controlled through an I2C
|
||||
interface.
|
||||
Ricoh RN5T567/RN5T618/RC5T619 is a power management IC family which
|
||||
integrates 3 to 5 step-down DCDC converters, 7 to 10 low-dropout regulators,
|
||||
GPIOs, and a watchdog timer. It can be controlled through an I2C interface.
|
||||
The RN5T618/RC5T619 provides additionally a Li-ion battery charger,
|
||||
fuel gauge, and an ADC.
|
||||
The RC5T619 additionnally includes USB charger detection and an RTC.
|
||||
|
||||
Required properties:
|
||||
- compatible: must be one of
|
||||
"ricoh,rn5t567"
|
||||
"ricoh,rn5t618"
|
||||
"ricoh,rc5t619"
|
||||
- reg: the I2C slave address of the device
|
||||
|
||||
Sub-nodes:
|
||||
- regulators: the node is required if the regulator functionality is
|
||||
needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, DCDC4
|
||||
(RN5T567), LDO1, LDO2, LDO3, LDO4, LDO5, LDORTC1 and LDORTC2.
|
||||
(RN5T567/RC5T619), LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, LDO8,
|
||||
LDO9, LDO10, LDORTC1 and LDORTC2.
|
||||
LDO7-10 are specific to RC5T619.
|
||||
The common bindings for each individual regulator can be found in:
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
|
@ -1,23 +1,78 @@
|
||||
TPS65218 family of regulators
|
||||
|
||||
Required properties:
|
||||
For tps65218 regulators/LDOs
|
||||
- compatible:
|
||||
- "ti,tps65218-dcdc1" for DCDC1
|
||||
- "ti,tps65218-dcdc2" for DCDC2
|
||||
- "ti,tps65218-dcdc3" for DCDC3
|
||||
- "ti,tps65218-dcdc4" for DCDC4
|
||||
- "ti,tps65218-dcdc5" for DCDC5
|
||||
- "ti,tps65218-dcdc6" for DCDC6
|
||||
- "ti,tps65218-ldo1" for LDO1
|
||||
- compatible: "ti,tps65218"
|
||||
- reg: I2C slave address
|
||||
|
||||
Optional properties:
|
||||
- Any optional property defined in bindings/regulator/regulator.txt
|
||||
- List of regulators provided by this controller, must be named
|
||||
after their hardware counterparts: dcdc[1-6] and ldo1
|
||||
- This is the list of child nodes that specify the regulator
|
||||
initialization data for defined regulators. Not all regulators for the given
|
||||
device need to be present. The definition for each of these nodes is defined
|
||||
using the standard binding for regulators found at ./regulator.txt.
|
||||
|
||||
The valid names for regulators are:
|
||||
tps65217: regulator-dcdc1, regulator-dcdc2, regulator-dcdc3, regulator-dcdc4,
|
||||
regulator-dcdc5, regulator-dcdc6, regulator-ldo1, regulator-ls3.
|
||||
Each regulator is defined using the standard binding for regulators.
|
||||
|
||||
Example:
|
||||
tps65218: tps65218@24 {
|
||||
reg = <0x24>;
|
||||
compatible = "ti,tps65218";
|
||||
interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
xyz: regulator@0 {
|
||||
compatible = "ti,tps65218-dcdc1";
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
dcdc1: regulator-dcdc1 {
|
||||
regulator-name = "vdd_core";
|
||||
regulator-min-microvolt = <912000>;
|
||||
regulator-max-microvolt = <1144000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
dcdc2: regulator-dcdc2 {
|
||||
regulator-name = "vdd_mpu";
|
||||
regulator-min-microvolt = <912000>;
|
||||
regulator-max-microvolt = <1378000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
dcdc3: regulator-dcdc3 {
|
||||
regulator-name = "vdcdc3";
|
||||
regulator-min-microvolt = <1500000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
dcdc5: regulator-dcdc5 {
|
||||
regulator-name = "v1_0bat";
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
dcdc6: regulator-dcdc6 {
|
||||
regulator-name = "v1_8bat";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo1: regulator-ldo1 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ls3: regulator-ls3 {
|
||||
regulator-min-microvolt = <100000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
};
|
||||
};
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/tps65218.h>
|
||||
|
||||
struct tps65218_gpio {
|
||||
@ -30,7 +31,7 @@ static int tps65218_gpio_get(struct gpio_chip *gc, unsigned offset)
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = tps65218_reg_read(tps65218, TPS65218_REG_ENABLE2, &val);
|
||||
ret = regmap_read(tps65218->regmap, TPS65218_REG_ENABLE2, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -150,12 +150,20 @@ static int tps6521x_pb_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id tps6521x_pwrbtn_id_table[] = {
|
||||
{ "tps65218-pwrbutton", },
|
||||
{ "tps65217-pwrbutton", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, tps6521x_pwrbtn_id_table);
|
||||
|
||||
static struct platform_driver tps6521x_pb_driver = {
|
||||
.probe = tps6521x_pb_probe,
|
||||
.driver = {
|
||||
.name = "tps6521x_pwrbutton",
|
||||
.of_match_table = of_tps6521x_pb_match,
|
||||
},
|
||||
.id_table = tps6521x_pwrbtn_id_table,
|
||||
};
|
||||
module_platform_driver(tps6521x_pb_driver);
|
||||
|
||||
|
@ -40,6 +40,22 @@ config MFD_ACT8945A
|
||||
linear regulators, along with a complete ActivePath battery
|
||||
charger.
|
||||
|
||||
config MFD_SUN4I_GPADC
|
||||
tristate "Allwinner sunxi platforms' GPADC MFD driver"
|
||||
select MFD_CORE
|
||||
select REGMAP_MMIO
|
||||
select REGMAP_IRQ
|
||||
depends on ARCH_SUNXI || COMPILE_TEST
|
||||
help
|
||||
Select this to get support for Allwinner SoCs (A10, A13 and A31) ADC.
|
||||
This driver will only map the hardware interrupt and registers, you
|
||||
have to select individual drivers based on this MFD to be able to use
|
||||
the ADC or the thermal sensor. This will try to probe the ADC driver
|
||||
sun4i-gpadc-iio and the hwmon driver iio_hwmon.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called sun4i-gpadc.
|
||||
|
||||
config MFD_AS3711
|
||||
bool "AMS AS3711"
|
||||
select MFD_CORE
|
||||
@ -293,6 +309,7 @@ config MFD_DLN2
|
||||
|
||||
config MFD_EXYNOS_LPASS
|
||||
tristate "Samsung Exynos SoC Low Power Audio Subsystem"
|
||||
depends on ARCH_EXYNOS || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
@ -563,7 +580,7 @@ config MFD_MAX14577
|
||||
config MFD_MAX77620
|
||||
bool "Maxim Semiconductor MAX77620 and MAX20024 PMIC Support"
|
||||
depends on I2C=y
|
||||
depends on OF
|
||||
depends on OF || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
@ -578,7 +595,7 @@ config MFD_MAX77620
|
||||
config MFD_MAX77686
|
||||
tristate "Maxim Semiconductor MAX77686/802 PMIC Support"
|
||||
depends on I2C
|
||||
depends on OF
|
||||
depends on OF || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
@ -877,7 +894,8 @@ config MFD_RN5T618
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say yes here to add support for the Ricoh RN5T567 or R5T618 PMIC.
|
||||
Say yes here to add support for the Ricoh RN5T567,
|
||||
RN5T618, RC5T619 PMIC.
|
||||
This driver provides common support for accessing the device,
|
||||
additional drivers must be enabled in order to use the
|
||||
functionality of the device.
|
||||
@ -951,7 +969,7 @@ config MFD_SMSC
|
||||
|
||||
config ABX500_CORE
|
||||
bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
|
||||
default y if ARCH_U300 || ARCH_U8500
|
||||
default y if ARCH_U300 || ARCH_U8500 || COMPILE_TEST
|
||||
help
|
||||
Say yes here if you have the ABX500 Mixed Signal IC family
|
||||
chips. This core driver expose register access functions.
|
||||
|
@ -211,3 +211,4 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
|
||||
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
|
||||
|
||||
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
|
||||
obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -628,20 +628,10 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100)
|
||||
exit_no_debugfs:
|
||||
return;
|
||||
}
|
||||
static inline void ab3100_remove_debugfs(void)
|
||||
{
|
||||
debugfs_remove(ab3100_set_reg_file);
|
||||
debugfs_remove(ab3100_get_reg_file);
|
||||
debugfs_remove(ab3100_reg_file);
|
||||
debugfs_remove(ab3100_dir);
|
||||
}
|
||||
#else
|
||||
static inline void ab3100_setup_debugfs(struct ab3100 *ab3100)
|
||||
{
|
||||
}
|
||||
static inline void ab3100_remove_debugfs(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -949,45 +939,22 @@ static int ab3100_probe(struct i2c_client *client,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ab3100_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ab3100 *ab3100 = i2c_get_clientdata(client);
|
||||
|
||||
/* Unregister subdevices */
|
||||
mfd_remove_devices(&client->dev);
|
||||
ab3100_remove_debugfs();
|
||||
i2c_unregister_device(ab3100->testreg_client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ab3100_id[] = {
|
||||
{ "ab3100", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ab3100_id);
|
||||
|
||||
static struct i2c_driver ab3100_driver = {
|
||||
.driver = {
|
||||
.name = "ab3100",
|
||||
.name = "ab3100",
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.id_table = ab3100_id,
|
||||
.probe = ab3100_probe,
|
||||
.remove = ab3100_remove,
|
||||
};
|
||||
|
||||
static int __init ab3100_i2c_init(void)
|
||||
{
|
||||
return i2c_add_driver(&ab3100_driver);
|
||||
}
|
||||
|
||||
static void __exit ab3100_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&ab3100_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(ab3100_i2c_init);
|
||||
module_exit(ab3100_i2c_exit);
|
||||
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
|
||||
MODULE_DESCRIPTION("AB3100 core driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
@ -123,6 +123,10 @@ static DEFINE_SPINLOCK(on_stat_lock);
|
||||
static u8 turn_on_stat_mask = 0xFF;
|
||||
static u8 turn_on_stat_set;
|
||||
static bool no_bm; /* No battery management */
|
||||
/*
|
||||
* not really modular, but the easiest way to keep compat with existing
|
||||
* bootargs behaviour is to continue using module_param here.
|
||||
*/
|
||||
module_param(no_bm, bool, S_IRUGO);
|
||||
|
||||
#define AB9540_MODEM_CTRL2_REG 0x23
|
||||
@ -1324,25 +1328,6 @@ static int ab8500_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ab8500_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ab8500 *ab8500 = platform_get_drvdata(pdev);
|
||||
|
||||
if (((is_ab8505(ab8500) || is_ab9540(ab8500)) &&
|
||||
ab8500->chip_id >= AB8500_CUT2P0) || is_ab8540(ab8500))
|
||||
sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group);
|
||||
else
|
||||
sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group);
|
||||
|
||||
if ((is_ab8505(ab8500) || is_ab9540(ab8500)) &&
|
||||
ab8500->chip_id >= AB8500_CUT2P0)
|
||||
sysfs_remove_group(&ab8500->dev->kobj, &ab8505_attr_group);
|
||||
|
||||
mfd_remove_devices(ab8500->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id ab8500_id[] = {
|
||||
{ "ab8500-core", AB8500_VERSION_AB8500 },
|
||||
{ "ab8505-i2c", AB8500_VERSION_AB8505 },
|
||||
@ -1354,9 +1339,9 @@ static const struct platform_device_id ab8500_id[] = {
|
||||
static struct platform_driver ab8500_core_driver = {
|
||||
.driver = {
|
||||
.name = "ab8500-core",
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = ab8500_probe,
|
||||
.remove = ab8500_remove,
|
||||
.id_table = ab8500_id,
|
||||
};
|
||||
|
||||
@ -1364,14 +1349,4 @@ static int __init ab8500_core_init(void)
|
||||
{
|
||||
return platform_driver_register(&ab8500_core_driver);
|
||||
}
|
||||
|
||||
static void __exit ab8500_core_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ab8500_core_driver);
|
||||
}
|
||||
core_initcall(ab8500_core_init);
|
||||
module_exit(ab8500_core_exit);
|
||||
|
||||
MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent");
|
||||
MODULE_DESCRIPTION("AB8500 MFD core");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -74,7 +74,7 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -3234,33 +3234,16 @@ err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int ab8500_debug_remove(struct platform_device *plf)
|
||||
{
|
||||
debugfs_remove_recursive(ab8500_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ab8500_debug_driver = {
|
||||
.driver = {
|
||||
.name = "ab8500-debug",
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = ab8500_debug_probe,
|
||||
.remove = ab8500_debug_remove
|
||||
};
|
||||
|
||||
static int __init ab8500_debug_init(void)
|
||||
{
|
||||
return platform_driver_register(&ab8500_debug_driver);
|
||||
}
|
||||
|
||||
static void __exit ab8500_debug_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ab8500_debug_driver);
|
||||
}
|
||||
subsys_initcall(ab8500_debug_init);
|
||||
module_exit(ab8500_debug_exit);
|
||||
|
||||
MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
|
||||
MODULE_DESCRIPTION("AB8500 DEBUG");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -5,9 +5,9 @@
|
||||
* Author: Arun R Murthy <arun.murthy@stericsson.com>
|
||||
* Author: Daniel Willerud <daniel.willerud@stericsson.com>
|
||||
* Author: Johan Palsson <johan.palsson@stericsson.com>
|
||||
* Author: M'boumba Cedric Madianga
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
@ -1054,11 +1054,7 @@ static int __init ab8500_gpadc_init(void)
|
||||
{
|
||||
return platform_driver_register(&ab8500_gpadc_driver);
|
||||
}
|
||||
|
||||
static void __exit ab8500_gpadc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ab8500_gpadc_driver);
|
||||
}
|
||||
subsys_initcall_sync(ab8500_gpadc_init);
|
||||
|
||||
/**
|
||||
* ab8540_gpadc_get_otp() - returns OTP values
|
||||
@ -1077,14 +1073,3 @@ void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc,
|
||||
*ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo;
|
||||
*ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi;
|
||||
}
|
||||
|
||||
subsys_initcall_sync(ab8500_gpadc_init);
|
||||
module_exit(ab8500_gpadc_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Arun R Murthy");
|
||||
MODULE_AUTHOR("Daniel Willerud");
|
||||
MODULE_AUTHOR("Johan Palsson");
|
||||
MODULE_AUTHOR("M'boumba Cedric Madianga");
|
||||
MODULE_ALIAS("platform:ab8500_gpadc");
|
||||
MODULE_DESCRIPTION("AB8500 GPADC driver");
|
||||
|
@ -1,11 +1,14 @@
|
||||
/*
|
||||
* AB8500 system control driver
|
||||
*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST Ericsson.
|
||||
* License terms: GNU General Public License (GPL) version 2
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/reboot.h>
|
||||
@ -158,7 +161,3 @@ static int __init ab8500_sysctrl_init(void)
|
||||
return platform_driver_register(&ab8500_sysctrl_driver);
|
||||
}
|
||||
arch_initcall(ab8500_sysctrl_init);
|
||||
|
||||
MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com");
|
||||
MODULE_DESCRIPTION("AB8500 system control driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -8,7 +8,8 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
|
||||
static LIST_HEAD(abx500_list);
|
||||
@ -150,7 +151,3 @@ int abx500_startup_irq_enabled(struct device *dev, unsigned int irq)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
EXPORT_SYMBOL(abx500_startup_irq_enabled);
|
||||
|
||||
MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
|
||||
MODULE_DESCRIPTION("ABX500 core driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -1553,6 +1553,7 @@ EXPORT_SYMBOL_GPL(arizona_dev_init);
|
||||
|
||||
int arizona_dev_exit(struct arizona *arizona)
|
||||
{
|
||||
disable_irq(arizona->irq);
|
||||
pm_runtime_disable(arizona->dev);
|
||||
|
||||
regulator_disable(arizona->dcvdd);
|
||||
|
@ -398,10 +398,10 @@ err_ctrlif:
|
||||
err_boot_done:
|
||||
free_irq(arizona->irq, arizona);
|
||||
err_main_irq:
|
||||
regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1),
|
||||
regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
|
||||
arizona->irq_chip);
|
||||
err_aod:
|
||||
regmap_del_irq_chip(irq_create_mapping(arizona->virq, 0),
|
||||
regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),
|
||||
arizona->aod_irq_chip);
|
||||
err:
|
||||
return ret;
|
||||
@ -413,9 +413,9 @@ int arizona_irq_exit(struct arizona *arizona)
|
||||
free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR),
|
||||
arizona);
|
||||
free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
|
||||
regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1),
|
||||
regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
|
||||
arizona->irq_chip);
|
||||
regmap_del_irq_chip(irq_create_mapping(arizona->virq, 0),
|
||||
regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),
|
||||
arizona->aod_irq_chip);
|
||||
free_irq(arizona->irq, arizona);
|
||||
|
||||
|
@ -69,10 +69,11 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
|
||||
|
||||
/*
|
||||
* This is useless for OF-enabled devices, but it is needed by I2C subsystem
|
||||
*/
|
||||
static const struct i2c_device_id axp20x_i2c_id[] = {
|
||||
{ "axp152", 0 },
|
||||
{ "axp202", 0 },
|
||||
{ "axp209", 0 },
|
||||
{ "axp221", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
|
||||
|
@ -98,6 +98,7 @@ 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(AXP22X_PMIC_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
|
||||
regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
|
||||
};
|
||||
|
||||
@ -135,6 +136,7 @@ static const struct regmap_range axp806_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
|
||||
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
|
||||
regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
|
||||
regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp806_volatile_ranges[] = {
|
||||
@ -305,7 +307,7 @@ static const struct regmap_config axp806_regmap_config = {
|
||||
.val_bits = 8,
|
||||
.wr_table = &axp806_writeable_table,
|
||||
.volatile_table = &axp806_volatile_table,
|
||||
.max_register = AXP806_VREF_TEMP_WARN_L,
|
||||
.max_register = AXP806_REG_ADDR_EXT,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
|
@ -67,7 +67,7 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
|
||||
/* Secondary I2C slave address is the base address with A(2) asserted */
|
||||
bcm590xx->i2c_sec = i2c_new_dummy(i2c_pri->adapter,
|
||||
i2c_pri->addr | BIT(2));
|
||||
if (IS_ERR_OR_NULL(bcm590xx->i2c_sec)) {
|
||||
if (!bcm590xx->i2c_sec) {
|
||||
dev_err(&i2c_pri->dev, "failed to add secondary I2C device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -292,6 +292,7 @@ static const struct reg_default cs47l24_reg_default[] = {
|
||||
{ 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */
|
||||
{ 0x00000503, 0x0000 }, /* R1283 - AIF1 Rate Ctrl */
|
||||
{ 0x00000504, 0x0000 }, /* R1284 - AIF1 Format */
|
||||
{ 0x00000505, 0x0040 }, /* R1285 - AIF1 Tx BCLK Rate */
|
||||
{ 0x00000506, 0x0040 }, /* R1286 - AIF1 Rx BCLK Rate */
|
||||
{ 0x00000507, 0x1818 }, /* R1287 - AIF1 Frame Ctrl 1 */
|
||||
{ 0x00000508, 0x1818 }, /* R1288 - AIF1 Frame Ctrl 2 */
|
||||
@ -318,6 +319,7 @@ static const struct reg_default cs47l24_reg_default[] = {
|
||||
{ 0x00000542, 0x0000 }, /* R1346 - AIF2 Rx Pin Ctrl */
|
||||
{ 0x00000543, 0x0000 }, /* R1347 - AIF2 Rate Ctrl */
|
||||
{ 0x00000544, 0x0000 }, /* R1348 - AIF2 Format */
|
||||
{ 0x00000545, 0x0040 }, /* R1349 - AIF2 Tx BCLK Rate */
|
||||
{ 0x00000546, 0x0040 }, /* R1350 - AIF2 Rx BCLK Rate */
|
||||
{ 0x00000547, 0x1818 }, /* R1351 - AIF2 Frame Ctrl 1 */
|
||||
{ 0x00000548, 0x1818 }, /* R1352 - AIF2 Frame Ctrl 2 */
|
||||
@ -340,6 +342,7 @@ static const struct reg_default cs47l24_reg_default[] = {
|
||||
{ 0x00000582, 0x0000 }, /* R1410 - AIF3 Rx Pin Ctrl */
|
||||
{ 0x00000583, 0x0000 }, /* R1411 - AIF3 Rate Ctrl */
|
||||
{ 0x00000584, 0x0000 }, /* R1412 - AIF3 Format */
|
||||
{ 0x00000585, 0x0040 }, /* R1413 - AIF3 Tx BCLK Rate */
|
||||
{ 0x00000586, 0x0040 }, /* R1414 - AIF3 Rx BCLK Rate */
|
||||
{ 0x00000587, 0x1818 }, /* R1415 - AIF3 Frame Ctrl 1 */
|
||||
{ 0x00000588, 0x1818 }, /* R1416 - AIF3 Frame Ctrl 2 */
|
||||
@ -923,6 +926,7 @@ static bool cs47l24_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_AIF1_RX_PIN_CTRL:
|
||||
case ARIZONA_AIF1_RATE_CTRL:
|
||||
case ARIZONA_AIF1_FORMAT:
|
||||
case ARIZONA_AIF1_TX_BCLK_RATE:
|
||||
case ARIZONA_AIF1_RX_BCLK_RATE:
|
||||
case ARIZONA_AIF1_FRAME_CTRL_1:
|
||||
case ARIZONA_AIF1_FRAME_CTRL_2:
|
||||
@ -949,6 +953,7 @@ static bool cs47l24_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_AIF2_RX_PIN_CTRL:
|
||||
case ARIZONA_AIF2_RATE_CTRL:
|
||||
case ARIZONA_AIF2_FORMAT:
|
||||
case ARIZONA_AIF2_TX_BCLK_RATE:
|
||||
case ARIZONA_AIF2_RX_BCLK_RATE:
|
||||
case ARIZONA_AIF2_FRAME_CTRL_1:
|
||||
case ARIZONA_AIF2_FRAME_CTRL_2:
|
||||
@ -971,6 +976,7 @@ static bool cs47l24_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_AIF3_RX_PIN_CTRL:
|
||||
case ARIZONA_AIF3_RATE_CTRL:
|
||||
case ARIZONA_AIF3_FORMAT:
|
||||
case ARIZONA_AIF3_TX_BCLK_RATE:
|
||||
case ARIZONA_AIF3_RX_BCLK_RATE:
|
||||
case ARIZONA_AIF3_FRAME_CTRL_1:
|
||||
case ARIZONA_AIF3_FRAME_CTRL_2:
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <sound/pcm.h>
|
||||
|
||||
#include <linux/mfd/davinci_voicecodec.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
static const struct regmap_config davinci_vc_regmap = {
|
||||
.reg_bits = 32,
|
||||
|
@ -187,6 +187,7 @@ static const struct of_device_id mx25_tsadc_ids[] = {
|
||||
{ .compatible = "fsl,imx25-tsadc" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mx25_tsadc_ids);
|
||||
|
||||
static struct platform_driver mx25_tsadc_driver = {
|
||||
.driver = {
|
||||
|
@ -169,6 +169,7 @@ static const struct of_device_id hi655x_pmic_match[] = {
|
||||
{ .compatible = "hisilicon,hi655x-pmic", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, hi655x_pmic_match);
|
||||
|
||||
static struct platform_driver hi655x_pmic_driver = {
|
||||
.driver = {
|
||||
|
@ -41,6 +41,7 @@ static int intel_lpss_pci_probe(struct pci_dev *pdev,
|
||||
|
||||
/* Probably it is enough to set this for iDMA capable devices only */
|
||||
pci_set_master(pdev);
|
||||
pci_try_set_mwi(pdev);
|
||||
|
||||
ret = intel_lpss_probe(&pdev->dev, info);
|
||||
if (ret)
|
||||
|
@ -519,7 +519,7 @@ static const struct acpi_device_id bxtwc_acpi_ids[] = {
|
||||
{ "INT34D3", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, pmic_acpi_ids);
|
||||
MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids);
|
||||
|
||||
static struct platform_driver bxtwc_driver = {
|
||||
.probe = bxtwc_probe,
|
||||
|
@ -493,6 +493,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
|
||||
[LPC_LPT] = {
|
||||
.name = "Lynx Point",
|
||||
.iTCO_version = 2,
|
||||
.gpio_version = ICH_V5_GPIO,
|
||||
},
|
||||
[LPC_LPT_LP] = {
|
||||
.name = "Lynx Point_LP",
|
||||
@ -530,6 +531,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
|
||||
[LPC_9S] = {
|
||||
.name = "9 Series",
|
||||
.iTCO_version = 2,
|
||||
.gpio_version = ICH_V5_GPIO,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -431,9 +431,6 @@ static void palmas_power_off(void)
|
||||
unsigned int addr;
|
||||
int ret, slave;
|
||||
|
||||
if (!palmas_dev)
|
||||
return;
|
||||
|
||||
slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE);
|
||||
addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_DEV_CTRL);
|
||||
|
||||
|
@ -39,6 +39,20 @@
|
||||
#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7)
|
||||
#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
|
||||
|
||||
#define PM8821_SSBI_REG_ADDR_IRQ_BASE 0x100
|
||||
#define PM8821_SSBI_REG_ADDR_IRQ_MASTER0 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0x30)
|
||||
#define PM8821_SSBI_REG_ADDR_IRQ_MASTER1 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0xb0)
|
||||
#define PM8821_SSBI_REG(m, b, offset) \
|
||||
((m == 0) ? \
|
||||
(PM8821_SSBI_REG_ADDR_IRQ_MASTER0 + b + offset) : \
|
||||
(PM8821_SSBI_REG_ADDR_IRQ_MASTER1 + b + offset))
|
||||
#define PM8821_SSBI_ADDR_IRQ_ROOT(m, b) PM8821_SSBI_REG(m, b, 0x0)
|
||||
#define PM8821_SSBI_ADDR_IRQ_CLEAR(m, b) PM8821_SSBI_REG(m, b, 0x01)
|
||||
#define PM8821_SSBI_ADDR_IRQ_MASK(m, b) PM8821_SSBI_REG(m, b, 0x08)
|
||||
#define PM8821_SSBI_ADDR_IRQ_RT_STATUS(m, b) PM8821_SSBI_REG(m, b, 0x0f)
|
||||
|
||||
#define PM8821_BLOCKS_PER_MASTER 7
|
||||
|
||||
#define PM_IRQF_LVL_SEL 0x01 /* level select */
|
||||
#define PM_IRQF_MASK_FE 0x02 /* mask falling edge */
|
||||
#define PM_IRQF_MASK_RE 0x04 /* mask rising edge */
|
||||
@ -54,6 +68,7 @@
|
||||
#define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */
|
||||
|
||||
#define PM8XXX_NR_IRQS 256
|
||||
#define PM8821_NR_IRQS 112
|
||||
|
||||
struct pm_irq_chip {
|
||||
struct regmap *regmap;
|
||||
@ -65,6 +80,12 @@ struct pm_irq_chip {
|
||||
u8 config[0];
|
||||
};
|
||||
|
||||
struct pm_irq_data {
|
||||
int num_irqs;
|
||||
const struct irq_domain_ops *irq_domain_ops;
|
||||
void (*irq_handler)(struct irq_desc *desc);
|
||||
};
|
||||
|
||||
static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
|
||||
unsigned int *ip)
|
||||
{
|
||||
@ -182,6 +203,78 @@ static void pm8xxx_irq_handler(struct irq_desc *desc)
|
||||
chained_irq_exit(irq_chip, desc);
|
||||
}
|
||||
|
||||
static void pm8821_irq_block_handler(struct pm_irq_chip *chip,
|
||||
int master, int block)
|
||||
{
|
||||
int pmirq, irq, i, ret;
|
||||
unsigned int bits;
|
||||
|
||||
ret = regmap_read(chip->regmap,
|
||||
PM8821_SSBI_ADDR_IRQ_ROOT(master, block), &bits);
|
||||
if (ret) {
|
||||
pr_err("Reading block %d failed ret=%d", block, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert block offset to global block number */
|
||||
block += (master * PM8821_BLOCKS_PER_MASTER) - 1;
|
||||
|
||||
/* Check IRQ bits */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (bits & BIT(i)) {
|
||||
pmirq = block * 8 + i;
|
||||
irq = irq_find_mapping(chip->irqdomain, pmirq);
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void pm8821_irq_master_handler(struct pm_irq_chip *chip,
|
||||
int master, u8 master_val)
|
||||
{
|
||||
int block;
|
||||
|
||||
for (block = 1; block < 8; block++)
|
||||
if (master_val & BIT(block))
|
||||
pm8821_irq_block_handler(chip, master, block);
|
||||
}
|
||||
|
||||
static void pm8821_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *irq_chip = irq_desc_get_chip(desc);
|
||||
unsigned int master;
|
||||
int ret;
|
||||
|
||||
chained_irq_enter(irq_chip, desc);
|
||||
ret = regmap_read(chip->regmap,
|
||||
PM8821_SSBI_REG_ADDR_IRQ_MASTER0, &master);
|
||||
if (ret) {
|
||||
pr_err("Failed to read master 0 ret=%d\n", ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* bits 1 through 7 marks the first 7 blocks in master 0 */
|
||||
if (master & GENMASK(7, 1))
|
||||
pm8821_irq_master_handler(chip, 0, master);
|
||||
|
||||
/* bit 0 marks if master 1 contains any bits */
|
||||
if (!(master & BIT(0)))
|
||||
goto done;
|
||||
|
||||
ret = regmap_read(chip->regmap,
|
||||
PM8821_SSBI_REG_ADDR_IRQ_MASTER1, &master);
|
||||
if (ret) {
|
||||
pr_err("Failed to read master 1 ret=%d\n", ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
pm8821_irq_master_handler(chip, 1, master);
|
||||
|
||||
done:
|
||||
chained_irq_exit(irq_chip, desc);
|
||||
}
|
||||
|
||||
static void pm8xxx_irq_mask_ack(struct irq_data *d)
|
||||
{
|
||||
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
|
||||
@ -299,6 +392,104 @@ static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
|
||||
.map = pm8xxx_irq_domain_map,
|
||||
};
|
||||
|
||||
static void pm8821_irq_mask_ack(struct irq_data *d)
|
||||
{
|
||||
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
|
||||
unsigned int pmirq = irqd_to_hwirq(d);
|
||||
u8 block, master;
|
||||
int irq_bit, rc;
|
||||
|
||||
block = pmirq / 8;
|
||||
master = block / PM8821_BLOCKS_PER_MASTER;
|
||||
irq_bit = pmirq % 8;
|
||||
block %= PM8821_BLOCKS_PER_MASTER;
|
||||
|
||||
rc = regmap_update_bits(chip->regmap,
|
||||
PM8821_SSBI_ADDR_IRQ_MASK(master, block),
|
||||
BIT(irq_bit), BIT(irq_bit));
|
||||
if (rc) {
|
||||
pr_err("Failed to mask IRQ:%d rc=%d\n", pmirq, rc);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = regmap_update_bits(chip->regmap,
|
||||
PM8821_SSBI_ADDR_IRQ_CLEAR(master, block),
|
||||
BIT(irq_bit), BIT(irq_bit));
|
||||
if (rc)
|
||||
pr_err("Failed to CLEAR IRQ:%d rc=%d\n", pmirq, rc);
|
||||
}
|
||||
|
||||
static void pm8821_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
|
||||
unsigned int pmirq = irqd_to_hwirq(d);
|
||||
int irq_bit, rc;
|
||||
u8 block, master;
|
||||
|
||||
block = pmirq / 8;
|
||||
master = block / PM8821_BLOCKS_PER_MASTER;
|
||||
irq_bit = pmirq % 8;
|
||||
block %= PM8821_BLOCKS_PER_MASTER;
|
||||
|
||||
rc = regmap_update_bits(chip->regmap,
|
||||
PM8821_SSBI_ADDR_IRQ_MASK(master, block),
|
||||
BIT(irq_bit), ~BIT(irq_bit));
|
||||
if (rc)
|
||||
pr_err("Failed to read/write unmask IRQ:%d rc=%d\n", pmirq, rc);
|
||||
|
||||
}
|
||||
|
||||
static int pm8821_irq_get_irqchip_state(struct irq_data *d,
|
||||
enum irqchip_irq_state which,
|
||||
bool *state)
|
||||
{
|
||||
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
|
||||
int rc, pmirq = irqd_to_hwirq(d);
|
||||
u8 block, irq_bit, master;
|
||||
unsigned int bits;
|
||||
|
||||
block = pmirq / 8;
|
||||
master = block / PM8821_BLOCKS_PER_MASTER;
|
||||
irq_bit = pmirq % 8;
|
||||
block %= PM8821_BLOCKS_PER_MASTER;
|
||||
|
||||
rc = regmap_read(chip->regmap,
|
||||
PM8821_SSBI_ADDR_IRQ_RT_STATUS(master, block), &bits);
|
||||
if (rc) {
|
||||
pr_err("Reading Status of IRQ %d failed rc=%d\n", pmirq, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*state = !!(bits & BIT(irq_bit));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct irq_chip pm8821_irq_chip = {
|
||||
.name = "pm8821",
|
||||
.irq_mask_ack = pm8821_irq_mask_ack,
|
||||
.irq_unmask = pm8821_irq_unmask,
|
||||
.irq_get_irqchip_state = pm8821_irq_get_irqchip_state,
|
||||
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static int pm8821_irq_domain_map(struct irq_domain *d, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
struct pm_irq_chip *chip = d->host_data;
|
||||
|
||||
irq_set_chip_and_handler(irq, &pm8821_irq_chip, handle_level_irq);
|
||||
irq_set_chip_data(irq, chip);
|
||||
irq_set_noprobe(irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops pm8821_irq_domain_ops = {
|
||||
.xlate = irq_domain_xlate_twocell,
|
||||
.map = pm8821_irq_domain_map,
|
||||
};
|
||||
|
||||
static const struct regmap_config ssbi_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
@ -308,22 +499,41 @@ static const struct regmap_config ssbi_regmap_config = {
|
||||
.reg_write = ssbi_reg_write
|
||||
};
|
||||
|
||||
static const struct pm_irq_data pm8xxx_data = {
|
||||
.num_irqs = PM8XXX_NR_IRQS,
|
||||
.irq_domain_ops = &pm8xxx_irq_domain_ops,
|
||||
.irq_handler = pm8xxx_irq_handler,
|
||||
};
|
||||
|
||||
static const struct pm_irq_data pm8821_data = {
|
||||
.num_irqs = PM8821_NR_IRQS,
|
||||
.irq_domain_ops = &pm8821_irq_domain_ops,
|
||||
.irq_handler = pm8821_irq_handler,
|
||||
};
|
||||
|
||||
static const struct of_device_id pm8xxx_id_table[] = {
|
||||
{ .compatible = "qcom,pm8018", },
|
||||
{ .compatible = "qcom,pm8058", },
|
||||
{ .compatible = "qcom,pm8921", },
|
||||
{ .compatible = "qcom,pm8018", .data = &pm8xxx_data},
|
||||
{ .compatible = "qcom,pm8058", .data = &pm8xxx_data},
|
||||
{ .compatible = "qcom,pm8821", .data = &pm8821_data},
|
||||
{ .compatible = "qcom,pm8921", .data = &pm8xxx_data},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
|
||||
|
||||
static int pm8xxx_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct pm_irq_data *data;
|
||||
struct regmap *regmap;
|
||||
int irq, rc;
|
||||
unsigned int val;
|
||||
u32 rev;
|
||||
struct pm_irq_chip *chip;
|
||||
unsigned int nirqs = PM8XXX_NR_IRQS;
|
||||
|
||||
data = of_device_get_match_data(&pdev->dev);
|
||||
if (!data) {
|
||||
dev_err(&pdev->dev, "No matching driver data found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
@ -354,25 +564,26 @@ static int pm8xxx_probe(struct platform_device *pdev)
|
||||
rev |= val << BITS_PER_BYTE;
|
||||
|
||||
chip = devm_kzalloc(&pdev->dev, sizeof(*chip) +
|
||||
sizeof(chip->config[0]) * nirqs,
|
||||
GFP_KERNEL);
|
||||
sizeof(chip->config[0]) * data->num_irqs,
|
||||
GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, chip);
|
||||
chip->regmap = regmap;
|
||||
chip->num_irqs = nirqs;
|
||||
chip->num_irqs = data->num_irqs;
|
||||
chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
|
||||
chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
|
||||
spin_lock_init(&chip->pm_irq_lock);
|
||||
|
||||
chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs,
|
||||
&pm8xxx_irq_domain_ops,
|
||||
chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
|
||||
data->num_irqs,
|
||||
data->irq_domain_ops,
|
||||
chip);
|
||||
if (!chip->irqdomain)
|
||||
return -ENODEV;
|
||||
|
||||
irq_set_chained_handler_and_data(irq, pm8xxx_irq_handler, chip);
|
||||
irq_set_chained_handler_and_data(irq, data->irq_handler, chip);
|
||||
irq_set_irq_wake(irq, 1);
|
||||
|
||||
rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
|
||||
|
@ -290,6 +290,24 @@ static void rk808_device_shutdown(void)
|
||||
dev_err(&rk808_i2c_client->dev, "power off error!\n");
|
||||
}
|
||||
|
||||
static void rk818_device_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
|
||||
|
||||
if (!rk808) {
|
||||
dev_warn(&rk808_i2c_client->dev,
|
||||
"have no rk818, so do nothing here\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(rk808->regmap,
|
||||
RK818_DEVCTRL_REG,
|
||||
DEV_OFF, DEV_OFF);
|
||||
if (ret)
|
||||
dev_err(&rk808_i2c_client->dev, "power off error!\n");
|
||||
}
|
||||
|
||||
static const struct of_device_id rk808_of_match[] = {
|
||||
{ .compatible = "rockchip,rk808" },
|
||||
{ .compatible = "rockchip,rk818" },
|
||||
@ -304,6 +322,7 @@ static int rk808_probe(struct i2c_client *client,
|
||||
struct rk808 *rk808;
|
||||
const struct rk808_reg_data *pre_init_reg;
|
||||
const struct mfd_cell *cells;
|
||||
void (*pm_pwroff_fn)(void);
|
||||
int nr_pre_init_regs;
|
||||
int nr_cells;
|
||||
int pm_off = 0;
|
||||
@ -331,6 +350,7 @@ static int rk808_probe(struct i2c_client *client,
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
|
||||
cells = rk808s;
|
||||
nr_cells = ARRAY_SIZE(rk808s);
|
||||
pm_pwroff_fn = rk808_device_shutdown;
|
||||
break;
|
||||
case RK818_ID:
|
||||
rk808->regmap_cfg = &rk818_regmap_config;
|
||||
@ -339,6 +359,7 @@ static int rk808_probe(struct i2c_client *client,
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
|
||||
cells = rk818s;
|
||||
nr_cells = ARRAY_SIZE(rk818s);
|
||||
pm_pwroff_fn = rk818_device_shutdown;
|
||||
break;
|
||||
default:
|
||||
dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
|
||||
@ -393,7 +414,7 @@ static int rk808_probe(struct i2c_client *client,
|
||||
"rockchip,system-power-controller");
|
||||
if (pm_off && !pm_power_off) {
|
||||
rk808_i2c_client = client;
|
||||
pm_power_off = rk808_device_shutdown;
|
||||
pm_power_off = pm_pwroff_fn;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -87,6 +87,7 @@ static int rn5t618_restart(struct notifier_block *this,
|
||||
static const struct of_device_id rn5t618_of_match[] = {
|
||||
{ .compatible = "ricoh,rn5t567", .data = (void *)RN5T567 },
|
||||
{ .compatible = "ricoh,rn5t618", .data = (void *)RN5T618 },
|
||||
{ .compatible = "ricoh,rc5t619", .data = (void *)RC5T619 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rn5t618_of_match);
|
||||
|
@ -753,7 +753,7 @@ static int si476x_core_probe(struct i2c_client *client,
|
||||
ARRAY_SIZE(core->supplies),
|
||||
core->supplies);
|
||||
if (rval) {
|
||||
dev_err(&client->dev, "Failet to gett all of the regulators\n");
|
||||
dev_err(&client->dev, "Failed to get all of the regulators\n");
|
||||
goto free_gpio;
|
||||
}
|
||||
|
||||
|
181
drivers/mfd/sun4i-gpadc.c
Normal file
181
drivers/mfd/sun4i-gpadc.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* ADC MFD core driver for sunxi platforms
|
||||
*
|
||||
* Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <linux/mfd/sun4i-gpadc.h>
|
||||
|
||||
#define ARCH_SUN4I_A10 0
|
||||
#define ARCH_SUN5I_A13 1
|
||||
#define ARCH_SUN6I_A31 2
|
||||
|
||||
static struct resource adc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(SUN4I_GPADC_IRQ_FIFO_DATA, "FIFO_DATA_PENDING"),
|
||||
DEFINE_RES_IRQ_NAMED(SUN4I_GPADC_IRQ_TEMP_DATA, "TEMP_DATA_PENDING"),
|
||||
};
|
||||
|
||||
static const struct regmap_irq sun4i_gpadc_regmap_irq[] = {
|
||||
REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_FIFO_DATA, 0,
|
||||
SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN),
|
||||
REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_TEMP_DATA, 0,
|
||||
SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip sun4i_gpadc_regmap_irq_chip = {
|
||||
.name = "sun4i_gpadc_irq_chip",
|
||||
.status_base = SUN4I_GPADC_INT_FIFOS,
|
||||
.ack_base = SUN4I_GPADC_INT_FIFOS,
|
||||
.mask_base = SUN4I_GPADC_INT_FIFOC,
|
||||
.init_ack_masked = true,
|
||||
.mask_invert = true,
|
||||
.irqs = sun4i_gpadc_regmap_irq,
|
||||
.num_irqs = ARRAY_SIZE(sun4i_gpadc_regmap_irq),
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static struct mfd_cell sun4i_gpadc_cells[] = {
|
||||
{
|
||||
.name = "sun4i-a10-gpadc-iio",
|
||||
.resources = adc_resources,
|
||||
.num_resources = ARRAY_SIZE(adc_resources),
|
||||
},
|
||||
{ .name = "iio_hwmon" }
|
||||
};
|
||||
|
||||
static struct mfd_cell sun5i_gpadc_cells[] = {
|
||||
{
|
||||
.name = "sun5i-a13-gpadc-iio",
|
||||
.resources = adc_resources,
|
||||
.num_resources = ARRAY_SIZE(adc_resources),
|
||||
},
|
||||
{ .name = "iio_hwmon" },
|
||||
};
|
||||
|
||||
static struct mfd_cell sun6i_gpadc_cells[] = {
|
||||
{
|
||||
.name = "sun6i-a31-gpadc-iio",
|
||||
.resources = adc_resources,
|
||||
.num_resources = ARRAY_SIZE(adc_resources),
|
||||
},
|
||||
{ .name = "iio_hwmon" },
|
||||
};
|
||||
|
||||
static const struct regmap_config sun4i_gpadc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id sun4i_gpadc_of_match[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun4i-a10-ts",
|
||||
.data = (void *)ARCH_SUN4I_A10,
|
||||
}, {
|
||||
.compatible = "allwinner,sun5i-a13-ts",
|
||||
.data = (void *)ARCH_SUN5I_A13,
|
||||
}, {
|
||||
.compatible = "allwinner,sun6i-a31-ts",
|
||||
.data = (void *)ARCH_SUN6I_A31,
|
||||
}, { /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_match);
|
||||
|
||||
static int sun4i_gpadc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sun4i_gpadc_dev *dev;
|
||||
struct resource *mem;
|
||||
const struct of_device_id *of_id;
|
||||
const struct mfd_cell *cells;
|
||||
unsigned int irq, size;
|
||||
int ret;
|
||||
|
||||
of_id = of_match_node(sun4i_gpadc_of_match, pdev->dev.of_node);
|
||||
if (!of_id)
|
||||
return -EINVAL;
|
||||
|
||||
switch ((long)of_id->data) {
|
||||
case ARCH_SUN4I_A10:
|
||||
cells = sun4i_gpadc_cells;
|
||||
size = ARRAY_SIZE(sun4i_gpadc_cells);
|
||||
break;
|
||||
case ARCH_SUN5I_A13:
|
||||
cells = sun5i_gpadc_cells;
|
||||
size = ARRAY_SIZE(sun5i_gpadc_cells);
|
||||
break;
|
||||
case ARCH_SUN6I_A31:
|
||||
cells = sun6i_gpadc_cells;
|
||||
size = ARRAY_SIZE(sun6i_gpadc_cells);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dev->base = devm_ioremap_resource(&pdev->dev, mem);
|
||||
if (IS_ERR(dev->base))
|
||||
return PTR_ERR(dev->base);
|
||||
|
||||
dev->dev = &pdev->dev;
|
||||
dev_set_drvdata(dev->dev, dev);
|
||||
|
||||
dev->regmap = devm_regmap_init_mmio(dev->dev, dev->base,
|
||||
&sun4i_gpadc_regmap_config);
|
||||
if (IS_ERR(dev->regmap)) {
|
||||
ret = PTR_ERR(dev->regmap);
|
||||
dev_err(&pdev->dev, "failed to init regmap: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable all interrupts */
|
||||
regmap_write(dev->regmap, SUN4I_GPADC_INT_FIFOC, 0);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
ret = devm_regmap_add_irq_chip(&pdev->dev, dev->regmap, irq,
|
||||
IRQF_ONESHOT, 0,
|
||||
&sun4i_gpadc_regmap_irq_chip,
|
||||
&dev->regmap_irqc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add irq chip: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(dev->dev, 0, cells, size, NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add MFD devices: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver sun4i_gpadc_driver = {
|
||||
.driver = {
|
||||
.name = "sun4i-gpadc",
|
||||
.of_match_table = of_match_ptr(sun4i_gpadc_of_match),
|
||||
},
|
||||
.probe = sun4i_gpadc_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(sun4i_gpadc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Allwinner sunxi platforms' GPADC MFD core driver");
|
||||
MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -53,7 +53,7 @@ int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg)
|
||||
EXPORT_SYMBOL_GPL(tc3589x_reg_read);
|
||||
|
||||
/**
|
||||
* tc3589x_reg_read() - write a single TC3589x register
|
||||
* tc3589x_reg_write() - write a single TC3589x register
|
||||
* @tc3589x: Device to write to
|
||||
* @reg: Register to read
|
||||
* @data: Value to write
|
||||
@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(tc3589x_block_write);
|
||||
* @tc3589x: Device to write to
|
||||
* @reg: Register to write
|
||||
* @mask: Mask of bits to set
|
||||
* @values: Value to set
|
||||
* @val: Value to set
|
||||
*/
|
||||
int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val)
|
||||
{
|
||||
|
@ -42,26 +42,6 @@ static struct resource pb_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_PB, "PB"),
|
||||
};
|
||||
|
||||
struct tps65217_irq {
|
||||
int mask;
|
||||
int interrupt;
|
||||
};
|
||||
|
||||
static const struct tps65217_irq tps65217_irqs[] = {
|
||||
[TPS65217_IRQ_PB] = {
|
||||
.mask = TPS65217_INT_PBM,
|
||||
.interrupt = TPS65217_INT_PBI,
|
||||
},
|
||||
[TPS65217_IRQ_AC] = {
|
||||
.mask = TPS65217_INT_ACM,
|
||||
.interrupt = TPS65217_INT_ACI,
|
||||
},
|
||||
[TPS65217_IRQ_USB] = {
|
||||
.mask = TPS65217_INT_USBM,
|
||||
.interrupt = TPS65217_INT_USBI,
|
||||
},
|
||||
};
|
||||
|
||||
static void tps65217_irq_lock(struct irq_data *data)
|
||||
{
|
||||
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
|
||||
@ -74,37 +54,32 @@ static void tps65217_irq_sync_unlock(struct irq_data *data)
|
||||
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
|
||||
int ret;
|
||||
|
||||
ret = tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask,
|
||||
TPS65217_PROTECT_NONE);
|
||||
ret = tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
|
||||
tps->irq_mask, TPS65217_PROTECT_NONE);
|
||||
if (ret != 0)
|
||||
dev_err(tps->dev, "Failed to sync IRQ masks\n");
|
||||
|
||||
mutex_unlock(&tps->irq_lock);
|
||||
}
|
||||
|
||||
static inline const struct tps65217_irq *
|
||||
irq_to_tps65217_irq(struct tps65217 *tps, struct irq_data *data)
|
||||
{
|
||||
return &tps65217_irqs[data->hwirq];
|
||||
}
|
||||
|
||||
static void tps65217_irq_enable(struct irq_data *data)
|
||||
{
|
||||
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
|
||||
const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data);
|
||||
u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
|
||||
|
||||
tps->irq_mask &= ~irq_data->mask;
|
||||
tps->irq_mask &= ~mask;
|
||||
}
|
||||
|
||||
static void tps65217_irq_disable(struct irq_data *data)
|
||||
{
|
||||
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
|
||||
const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data);
|
||||
u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
|
||||
|
||||
tps->irq_mask |= irq_data->mask;
|
||||
tps->irq_mask |= mask;
|
||||
}
|
||||
|
||||
static struct irq_chip tps65217_irq_chip = {
|
||||
.name = "tps65217",
|
||||
.irq_bus_lock = tps65217_irq_lock,
|
||||
.irq_bus_sync_unlock = tps65217_irq_sync_unlock,
|
||||
.irq_enable = tps65217_irq_enable,
|
||||
@ -149,8 +124,8 @@ static irqreturn_t tps65217_irq_thread(int irq, void *data)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tps65217_irqs); i++) {
|
||||
if (status & tps65217_irqs[i].interrupt) {
|
||||
for (i = 0; i < TPS65217_NUM_IRQ; i++) {
|
||||
if (status & BIT(i)) {
|
||||
handle_nested_irq(irq_find_mapping(tps->irq_domain, i));
|
||||
handled = true;
|
||||
}
|
||||
@ -188,10 +163,9 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq)
|
||||
tps->irq = irq;
|
||||
|
||||
/* Mask all interrupt sources */
|
||||
tps->irq_mask = (TPS65217_INT_RESERVEDM | TPS65217_INT_PBM
|
||||
| TPS65217_INT_ACM | TPS65217_INT_USBM);
|
||||
tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask,
|
||||
TPS65217_PROTECT_NONE);
|
||||
tps->irq_mask = TPS65217_INT_MASK;
|
||||
tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
|
||||
TPS65217_INT_MASK, TPS65217_PROTECT_NONE);
|
||||
|
||||
tps->irq_domain = irq_domain_add_linear(tps->dev->of_node,
|
||||
TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps);
|
||||
@ -209,6 +183,8 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq)
|
||||
return ret;
|
||||
}
|
||||
|
||||
enable_irq_wake(irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -424,6 +400,24 @@ static int tps65217_probe(struct i2c_client *client,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65217_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tps65217 *tps = i2c_get_clientdata(client);
|
||||
unsigned int virq;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TPS65217_NUM_IRQ; i++) {
|
||||
virq = irq_find_mapping(tps->irq_domain, i);
|
||||
if (virq)
|
||||
irq_dispose_mapping(virq);
|
||||
}
|
||||
|
||||
irq_domain_remove(tps->irq_domain);
|
||||
tps->irq_domain = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps65217_id_table[] = {
|
||||
{"tps65217", TPS65217},
|
||||
{ /* sentinel */ }
|
||||
@ -437,6 +431,7 @@ static struct i2c_driver tps65217_driver = {
|
||||
},
|
||||
.id_table = tps65217_id_table,
|
||||
.probe = tps65217_probe,
|
||||
.remove = tps65217_remove,
|
||||
};
|
||||
|
||||
static int __init tps65217_init(void)
|
||||
|
@ -33,19 +33,17 @@
|
||||
|
||||
#define TPS65218_PASSWORD_REGS_UNLOCK 0x7D
|
||||
|
||||
/**
|
||||
* tps65218_reg_read: Read a single tps65218 register.
|
||||
*
|
||||
* @tps: Device to read from.
|
||||
* @reg: Register to read.
|
||||
* @val: Contians the value
|
||||
*/
|
||||
int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
|
||||
unsigned int *val)
|
||||
{
|
||||
return regmap_read(tps->regmap, reg, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tps65218_reg_read);
|
||||
static const struct mfd_cell tps65218_cells[] = {
|
||||
{
|
||||
.name = "tps65218-pwrbutton",
|
||||
.of_compatible = "ti,tps65218-pwrbutton",
|
||||
},
|
||||
{
|
||||
.name = "tps65218-gpio",
|
||||
.of_compatible = "ti,tps65218-gpio",
|
||||
},
|
||||
{ .name = "tps65218-regulator", },
|
||||
};
|
||||
|
||||
/**
|
||||
* tps65218_reg_write: Write a single tps65218 register.
|
||||
@ -93,7 +91,7 @@ static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg,
|
||||
int ret;
|
||||
unsigned int data;
|
||||
|
||||
ret = tps65218_reg_read(tps, reg, &data);
|
||||
ret = regmap_read(tps->regmap, reg, &data);
|
||||
if (ret) {
|
||||
dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
|
||||
return ret;
|
||||
@ -251,7 +249,7 @@ static int tps65218_probe(struct i2c_client *client,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = tps65218_reg_read(tps, TPS65218_REG_CHIPID, &chipid);
|
||||
ret = regmap_read(tps->regmap, TPS65218_REG_CHIPID, &chipid);
|
||||
if (ret) {
|
||||
dev_err(tps->dev, "Failed to read chipid: %d\n", ret);
|
||||
return ret;
|
||||
@ -259,8 +257,10 @@ static int tps65218_probe(struct i2c_client *client,
|
||||
|
||||
tps->rev = chipid & TPS65218_CHIPID_REV_MASK;
|
||||
|
||||
ret = of_platform_populate(client->dev.of_node, NULL, NULL,
|
||||
&client->dev);
|
||||
ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65218_cells,
|
||||
ARRAY_SIZE(tps65218_cells), NULL, 0,
|
||||
regmap_irq_get_domain(tps->irq_data));
|
||||
|
||||
if (ret < 0)
|
||||
goto err_irq;
|
||||
|
||||
|
@ -77,6 +77,23 @@ static struct regmap_irq_chip tps65912_irq_chip = {
|
||||
.init_ack_masked = true,
|
||||
};
|
||||
|
||||
static const struct regmap_range tps65912_yes_ranges[] = {
|
||||
regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table tps65912_volatile_table = {
|
||||
.yes_ranges = tps65912_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
|
||||
};
|
||||
|
||||
const struct regmap_config tps65912_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_table = &tps65912_volatile_table,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(tps65912_regmap_config);
|
||||
|
||||
int tps65912_device_init(struct tps65912 *tps)
|
||||
{
|
||||
int ret;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -406,8 +406,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regulator_bulk_enable(wm8994->num_supplies,
|
||||
wm8994->supplies);
|
||||
ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies);
|
||||
if (ret != 0) {
|
||||
dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
|
||||
goto err_regulator_free;
|
||||
@ -612,8 +611,7 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
|
||||
{
|
||||
pm_runtime_disable(wm8994->dev);
|
||||
wm8994_irq_exit(wm8994);
|
||||
regulator_bulk_disable(wm8994->num_supplies,
|
||||
wm8994->supplies);
|
||||
regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);
|
||||
regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
|
||||
mfd_remove_devices(wm8994->dev);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
@ -30,10 +31,11 @@
|
||||
enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4,
|
||||
DCDC5, DCDC6, LDO1, LS3 };
|
||||
|
||||
#define TPS65218_REGULATOR(_name, _id, _type, _ops, _n, _vr, _vm, _er, _em, \
|
||||
_cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \
|
||||
#define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
|
||||
_em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.of_match = _of, \
|
||||
.id = _id, \
|
||||
.ops = &_ops, \
|
||||
.n_voltages = _n, \
|
||||
@ -54,14 +56,6 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4,
|
||||
.bypass_mask = _sm, \
|
||||
} \
|
||||
|
||||
#define TPS65218_INFO(_id, _nm, _min, _max) \
|
||||
[_id] = { \
|
||||
.id = _id, \
|
||||
.name = _nm, \
|
||||
.min_uV = _min, \
|
||||
.max_uV = _max, \
|
||||
}
|
||||
|
||||
static const struct regulator_linear_range dcdc1_dcdc2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000),
|
||||
@ -77,36 +71,6 @@ static const struct regulator_linear_range dcdc4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000),
|
||||
};
|
||||
|
||||
static struct tps_info tps65218_pmic_regs[] = {
|
||||
TPS65218_INFO(DCDC1, "DCDC1", 850000, 1675000),
|
||||
TPS65218_INFO(DCDC2, "DCDC2", 850000, 1675000),
|
||||
TPS65218_INFO(DCDC3, "DCDC3", 900000, 3400000),
|
||||
TPS65218_INFO(DCDC4, "DCDC4", 1175000, 3400000),
|
||||
TPS65218_INFO(DCDC5, "DCDC5", 1000000, 1000000),
|
||||
TPS65218_INFO(DCDC6, "DCDC6", 1800000, 1800000),
|
||||
TPS65218_INFO(LDO1, "LDO1", 900000, 3400000),
|
||||
TPS65218_INFO(LS3, "LS3", -1, -1),
|
||||
};
|
||||
|
||||
#define TPS65218_OF_MATCH(comp, label) \
|
||||
{ \
|
||||
.compatible = comp, \
|
||||
.data = &label, \
|
||||
}
|
||||
|
||||
static const struct of_device_id tps65218_of_match[] = {
|
||||
TPS65218_OF_MATCH("ti,tps65218-dcdc1", tps65218_pmic_regs[DCDC1]),
|
||||
TPS65218_OF_MATCH("ti,tps65218-dcdc2", tps65218_pmic_regs[DCDC2]),
|
||||
TPS65218_OF_MATCH("ti,tps65218-dcdc3", tps65218_pmic_regs[DCDC3]),
|
||||
TPS65218_OF_MATCH("ti,tps65218-dcdc4", tps65218_pmic_regs[DCDC4]),
|
||||
TPS65218_OF_MATCH("ti,tps65218-dcdc5", tps65218_pmic_regs[DCDC5]),
|
||||
TPS65218_OF_MATCH("ti,tps65218-dcdc6", tps65218_pmic_regs[DCDC6]),
|
||||
TPS65218_OF_MATCH("ti,tps65218-ldo1", tps65218_pmic_regs[LDO1]),
|
||||
TPS65218_OF_MATCH("ti,tps65218-ls3", tps65218_pmic_regs[LS3]),
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tps65218_of_match);
|
||||
|
||||
static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev,
|
||||
unsigned selector)
|
||||
{
|
||||
@ -188,7 +152,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
|
||||
if (rid == TPS65218_DCDC_3 && tps->rev == TPS65218_REV_2_1)
|
||||
return 0;
|
||||
|
||||
if (!tps->info[rid]->strobe) {
|
||||
if (!tps->strobes[rid]) {
|
||||
if (rid == TPS65218_DCDC_3)
|
||||
tps->info[rid]->strobe = 3;
|
||||
else
|
||||
@ -197,8 +161,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
|
||||
|
||||
return tps65218_set_bits(tps, dev->desc->bypass_reg,
|
||||
dev->desc->bypass_mask,
|
||||
tps->info[rid]->strobe,
|
||||
TPS65218_PROTECT_L1);
|
||||
tps->strobes[rid], TPS65218_PROTECT_L1);
|
||||
}
|
||||
|
||||
/* Operations permitted on DCDC1, DCDC2 */
|
||||
@ -272,7 +235,7 @@ static int tps65218_pmic_get_current_limit(struct regulator_dev *dev)
|
||||
unsigned int index;
|
||||
struct tps65218 *tps = rdev_get_drvdata(dev);
|
||||
|
||||
retval = tps65218_reg_read(tps, dev->desc->csel_reg, &index);
|
||||
retval = regmap_read(tps->regmap, dev->desc->csel_reg, &index);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
@ -300,104 +263,104 @@ static struct regulator_ops tps65218_dcdc56_pmic_ops = {
|
||||
};
|
||||
|
||||
static const struct regulator_desc regulators[] = {
|
||||
TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, REGULATOR_VOLTAGE,
|
||||
tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC1,
|
||||
TPS65218_REGULATOR("DCDC1", "regulator-dcdc1", TPS65218_DCDC_1,
|
||||
REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64,
|
||||
TPS65218_REG_CONTROL_DCDC1,
|
||||
TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges,
|
||||
2, 4000, 0, TPS65218_REG_SEQ3,
|
||||
TPS65218_SEQ3_DC1_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, REGULATOR_VOLTAGE,
|
||||
tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2,
|
||||
TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2,
|
||||
REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64,
|
||||
TPS65218_REG_CONTROL_DCDC2,
|
||||
TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges,
|
||||
2, 4000, 0, TPS65218_REG_SEQ3,
|
||||
TPS65218_SEQ3_DC2_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, REGULATOR_VOLTAGE,
|
||||
tps65218_ldo1_dcdc34_ops, 64,
|
||||
TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3,
|
||||
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64,
|
||||
TPS65218_REG_CONTROL_DCDC3,
|
||||
TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2,
|
||||
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, REGULATOR_VOLTAGE,
|
||||
tps65218_ldo1_dcdc34_ops, 53,
|
||||
TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4,
|
||||
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53,
|
||||
TPS65218_REG_CONTROL_DCDC4,
|
||||
TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2,
|
||||
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, REGULATOR_VOLTAGE,
|
||||
tps65218_dcdc56_pmic_ops, 1, -1, -1,
|
||||
TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0,
|
||||
NULL, 0, 0, 1000000, TPS65218_REG_SEQ5,
|
||||
TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5,
|
||||
REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1,
|
||||
-1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0,
|
||||
0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5,
|
||||
TPS65218_SEQ5_DC5_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, REGULATOR_VOLTAGE,
|
||||
tps65218_dcdc56_pmic_ops, 1, -1, -1,
|
||||
TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0,
|
||||
NULL, 0, 0, 1800000, TPS65218_REG_SEQ5,
|
||||
TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6,
|
||||
REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1,
|
||||
-1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0,
|
||||
0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5,
|
||||
TPS65218_SEQ5_DC6_SEQ_MASK),
|
||||
TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, REGULATOR_VOLTAGE,
|
||||
tps65218_ldo1_dcdc34_ops, 64,
|
||||
TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1,
|
||||
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64,
|
||||
TPS65218_REG_CONTROL_LDO1,
|
||||
TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
|
||||
TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges,
|
||||
2, 0, 0, TPS65218_REG_SEQ6,
|
||||
TPS65218_SEQ6_LDO1_SEQ_MASK),
|
||||
TPS65218_REGULATOR("LS3", TPS65218_LS_3, REGULATOR_CURRENT,
|
||||
tps65218_ls3_ops, 0, 0, 0, TPS65218_REG_ENABLE2,
|
||||
TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2,
|
||||
TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0, 0, 0),
|
||||
TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3,
|
||||
REGULATOR_CURRENT, tps65218_ls3_ops, 0, 0, 0,
|
||||
TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN,
|
||||
TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK,
|
||||
NULL, 0, 0, 0, 0, 0),
|
||||
};
|
||||
|
||||
static int tps65218_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_init_data *init_data;
|
||||
const struct tps_info *template;
|
||||
struct regulator_dev *rdev;
|
||||
const struct of_device_id *match;
|
||||
struct regulator_config config = { };
|
||||
int id, ret;
|
||||
int i, ret;
|
||||
unsigned int val;
|
||||
|
||||
match = of_match_device(tps65218_of_match, &pdev->dev);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
template = match->data;
|
||||
id = template->id;
|
||||
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
|
||||
®ulators[id]);
|
||||
|
||||
platform_set_drvdata(pdev, tps);
|
||||
|
||||
tps->info[id] = &tps65218_pmic_regs[id];
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = init_data;
|
||||
config.dev->of_node = tps->dev->of_node;
|
||||
config.driver_data = tps;
|
||||
config.regmap = tps->regmap;
|
||||
config.of_node = pdev->dev.of_node;
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev, ®ulators[id], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(tps->dev, "failed to register %s regulator\n",
|
||||
pdev->name);
|
||||
return PTR_ERR(rdev);
|
||||
/* Allocate memory for strobes */
|
||||
tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) *
|
||||
TPS65218_NUM_REGULATOR, GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
|
||||
rdev = devm_regulator_register(&pdev->dev, ®ulators[i],
|
||||
&config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(tps->dev, "failed to register %s regulator\n",
|
||||
pdev->name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
ret = regmap_read(tps->regmap, regulators[i].bypass_reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tps->strobes[i] = val & regulators[i].bypass_mask;
|
||||
}
|
||||
|
||||
ret = tps65218_reg_read(tps, regulators[id].bypass_reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tps->info[id]->strobe = val & regulators[id].bypass_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id tps65218_regulator_id_table[] = {
|
||||
{ "tps65218-regulator", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, tps65218_regulator_id_table);
|
||||
|
||||
static struct platform_driver tps65218_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "tps65218-pmic",
|
||||
.of_match_table = tps65218_of_match,
|
||||
},
|
||||
.probe = tps65218_regulator_probe,
|
||||
.id_table = tps65218_regulator_id_table,
|
||||
};
|
||||
|
||||
module_platform_driver(tps65218_regulator_driver);
|
||||
|
@ -115,6 +115,8 @@ enum {
|
||||
#define AXP806_CLDO2_V_CTRL 0x25
|
||||
#define AXP806_CLDO3_V_CTRL 0x26
|
||||
#define AXP806_VREF_TEMP_WARN_L 0xf3
|
||||
#define AXP806_BUS_ADDR_EXT 0xfe
|
||||
#define AXP806_REG_ADDR_EXT 0xff
|
||||
|
||||
/* Interrupt */
|
||||
#define AXP152_IRQ1_EN 0x40
|
||||
@ -226,6 +228,10 @@ enum {
|
||||
#define AXP20X_OCV_MAX 0xf
|
||||
|
||||
/* AXP22X specific registers */
|
||||
#define AXP22X_PMIC_ADC_H 0x56
|
||||
#define AXP22X_PMIC_ADC_L 0x57
|
||||
#define AXP22X_TS_ADC_H 0x58
|
||||
#define AXP22X_TS_ADC_L 0x59
|
||||
#define AXP22X_BATLOW_THRES1 0xe6
|
||||
|
||||
/* AXP288 specific registers */
|
||||
|
@ -28,8 +28,6 @@
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/platform_data/edma.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
struct regmap;
|
||||
|
||||
/*
|
||||
@ -99,8 +97,6 @@ struct davinci_vcif {
|
||||
dma_addr_t dma_rx_addr;
|
||||
};
|
||||
|
||||
struct davinci_vc;
|
||||
|
||||
struct davinci_vc {
|
||||
/* Device data */
|
||||
struct device *dev;
|
||||
|
@ -290,6 +290,7 @@ enum rk818_reg {
|
||||
#define SWITCH2_EN BIT(6)
|
||||
#define SWITCH1_EN BIT(5)
|
||||
#define DEV_OFF_RST BIT(3)
|
||||
#define DEV_OFF BIT(0)
|
||||
|
||||
#define VB_LO_ACT BIT(4)
|
||||
#define VB_LO_SEL_3500MV (7 << 0)
|
||||
|
@ -58,10 +58,13 @@
|
||||
#define RN5T618_DC3CTL2 0x31
|
||||
#define RN5T618_DC4CTL 0x32
|
||||
#define RN5T618_DC4CTL2 0x33
|
||||
#define RN5T618_DC5CTL 0x34
|
||||
#define RN5T618_DC5CTL2 0x35
|
||||
#define RN5T618_DC1DAC 0x36
|
||||
#define RN5T618_DC2DAC 0x37
|
||||
#define RN5T618_DC3DAC 0x38
|
||||
#define RN5T618_DC4DAC 0x39
|
||||
#define RN5T618_DC5DAC 0x3a
|
||||
#define RN5T618_DC1DAC_SLP 0x3b
|
||||
#define RN5T618_DC2DAC_SLP 0x3c
|
||||
#define RN5T618_DC3DAC_SLP 0x3d
|
||||
@ -77,6 +80,11 @@
|
||||
#define RN5T618_LDO3DAC 0x4e
|
||||
#define RN5T618_LDO4DAC 0x4f
|
||||
#define RN5T618_LDO5DAC 0x50
|
||||
#define RN5T618_LDO6DAC 0x51
|
||||
#define RN5T618_LDO7DAC 0x52
|
||||
#define RN5T618_LDO8DAC 0x53
|
||||
#define RN5T618_LDO9DAC 0x54
|
||||
#define RN5T618_LDO10DAC 0x55
|
||||
#define RN5T618_LDORTCDAC 0x56
|
||||
#define RN5T618_LDORTC2DAC 0x57
|
||||
#define RN5T618_LDO1DAC_SLP 0x58
|
||||
@ -231,6 +239,7 @@ enum {
|
||||
enum {
|
||||
RN5T567 = 0,
|
||||
RN5T618,
|
||||
RC5T619,
|
||||
};
|
||||
|
||||
struct rn5t618 {
|
||||
|
94
include/linux/mfd/sun4i-gpadc.h
Normal file
94
include/linux/mfd/sun4i-gpadc.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* Header of ADC MFD core driver for sunxi platforms
|
||||
*
|
||||
* Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __SUN4I_GPADC__H__
|
||||
#define __SUN4I_GPADC__H__
|
||||
|
||||
#define SUN4I_GPADC_CTRL0 0x00
|
||||
|
||||
#define SUN4I_GPADC_CTRL0_ADC_FIRST_DLY(x) ((GENMASK(7, 0) & (x)) << 24)
|
||||
#define SUN4I_GPADC_CTRL0_ADC_FIRST_DLY_MODE BIT(23)
|
||||
#define SUN4I_GPADC_CTRL0_ADC_CLK_SELECT BIT(22)
|
||||
#define SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(x) ((GENMASK(1, 0) & (x)) << 20)
|
||||
#define SUN4I_GPADC_CTRL0_FS_DIV(x) ((GENMASK(3, 0) & (x)) << 16)
|
||||
#define SUN4I_GPADC_CTRL0_T_ACQ(x) (GENMASK(15, 0) & (x))
|
||||
|
||||
#define SUN4I_GPADC_CTRL1 0x04
|
||||
|
||||
#define SUN4I_GPADC_CTRL1_STYLUS_UP_DEBOUNCE(x) ((GENMASK(7, 0) & (x)) << 12)
|
||||
#define SUN4I_GPADC_CTRL1_STYLUS_UP_DEBOUNCE_EN BIT(9)
|
||||
#define SUN4I_GPADC_CTRL1_TOUCH_PAN_CALI_EN BIT(6)
|
||||
#define SUN4I_GPADC_CTRL1_TP_DUAL_EN BIT(5)
|
||||
#define SUN4I_GPADC_CTRL1_TP_MODE_EN BIT(4)
|
||||
#define SUN4I_GPADC_CTRL1_TP_ADC_SELECT BIT(3)
|
||||
#define SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(2, 0) & (x))
|
||||
|
||||
/* TP_CTRL1 bits for sun6i SOCs */
|
||||
#define SUN6I_GPADC_CTRL1_TOUCH_PAN_CALI_EN BIT(7)
|
||||
#define SUN6I_GPADC_CTRL1_TP_DUAL_EN BIT(6)
|
||||
#define SUN6I_GPADC_CTRL1_TP_MODE_EN BIT(5)
|
||||
#define SUN6I_GPADC_CTRL1_TP_ADC_SELECT BIT(4)
|
||||
#define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(3, 0) & BIT(x))
|
||||
|
||||
#define SUN4I_GPADC_CTRL2 0x08
|
||||
|
||||
#define SUN4I_GPADC_CTRL2_TP_SENSITIVE_ADJUST(x) ((GENMASK(3, 0) & (x)) << 28)
|
||||
#define SUN4I_GPADC_CTRL2_TP_MODE_SELECT(x) ((GENMASK(1, 0) & (x)) << 26)
|
||||
#define SUN4I_GPADC_CTRL2_PRE_MEA_EN BIT(24)
|
||||
#define SUN4I_GPADC_CTRL2_PRE_MEA_THRE_CNT(x) (GENMASK(23, 0) & (x))
|
||||
|
||||
#define SUN4I_GPADC_CTRL3 0x0c
|
||||
|
||||
#define SUN4I_GPADC_CTRL3_FILTER_EN BIT(2)
|
||||
#define SUN4I_GPADC_CTRL3_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
|
||||
|
||||
#define SUN4I_GPADC_TPR 0x18
|
||||
|
||||
#define SUN4I_GPADC_TPR_TEMP_ENABLE BIT(16)
|
||||
#define SUN4I_GPADC_TPR_TEMP_PERIOD(x) (GENMASK(15, 0) & (x))
|
||||
|
||||
#define SUN4I_GPADC_INT_FIFOC 0x10
|
||||
|
||||
#define SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN BIT(18)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_OVERRUN_IRQ_EN BIT(17)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN BIT(16)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_DATA_XY_CHANGE BIT(13)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(x) ((GENMASK(4, 0) & (x)) << 8)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_DATA_DRQ_EN BIT(7)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH BIT(4)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_UP_IRQ_EN BIT(1)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_DOWN_IRQ_EN BIT(0)
|
||||
|
||||
#define SUN4I_GPADC_INT_FIFOS 0x14
|
||||
|
||||
#define SUN4I_GPADC_INT_FIFOS_TEMP_DATA_PENDING BIT(18)
|
||||
#define SUN4I_GPADC_INT_FIFOS_FIFO_OVERRUN_PENDING BIT(17)
|
||||
#define SUN4I_GPADC_INT_FIFOS_FIFO_DATA_PENDING BIT(16)
|
||||
#define SUN4I_GPADC_INT_FIFOS_TP_IDLE_FLG BIT(2)
|
||||
#define SUN4I_GPADC_INT_FIFOS_TP_UP_PENDING BIT(1)
|
||||
#define SUN4I_GPADC_INT_FIFOS_TP_DOWN_PENDING BIT(0)
|
||||
|
||||
#define SUN4I_GPADC_CDAT 0x1c
|
||||
#define SUN4I_GPADC_TEMP_DATA 0x20
|
||||
#define SUN4I_GPADC_DATA 0x24
|
||||
|
||||
#define SUN4I_GPADC_IRQ_FIFO_DATA 0
|
||||
#define SUN4I_GPADC_IRQ_TEMP_DATA 1
|
||||
|
||||
/* 10s delay before suspending the IP */
|
||||
#define SUN4I_GPADC_AUTOSUSPEND_DELAY 10000
|
||||
|
||||
struct sun4i_gpadc_dev {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct regmap_irq_chip_data *regmap_irqc;
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
#endif
|
@ -73,13 +73,15 @@
|
||||
#define TPS65217_PPATH_AC_CURRENT_MASK 0x0C
|
||||
#define TPS65217_PPATH_USB_CURRENT_MASK 0x03
|
||||
|
||||
#define TPS65217_INT_RESERVEDM BIT(7)
|
||||
#define TPS65217_INT_PBM BIT(6)
|
||||
#define TPS65217_INT_ACM BIT(5)
|
||||
#define TPS65217_INT_USBM BIT(4)
|
||||
#define TPS65217_INT_PBI BIT(2)
|
||||
#define TPS65217_INT_ACI BIT(1)
|
||||
#define TPS65217_INT_USBI BIT(0)
|
||||
#define TPS65217_INT_SHIFT 4
|
||||
#define TPS65217_INT_MASK (TPS65217_INT_PBM | TPS65217_INT_ACM | \
|
||||
TPS65217_INT_USBM)
|
||||
|
||||
#define TPS65217_CHGCONFIG0_TREG BIT(7)
|
||||
#define TPS65217_CHGCONFIG0_DPPM BIT(6)
|
||||
|
@ -282,10 +282,9 @@ struct tps65218 {
|
||||
struct regulator_desc desc[TPS65218_NUM_REGULATOR];
|
||||
struct tps_info *info[TPS65218_NUM_REGULATOR];
|
||||
struct regmap *regmap;
|
||||
u8 *strobes;
|
||||
};
|
||||
|
||||
int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
|
||||
unsigned int *val);
|
||||
int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
|
||||
unsigned int val, unsigned int level);
|
||||
int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,
|
||||
|
@ -319,21 +319,7 @@ struct tps65912 {
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
};
|
||||
|
||||
static const struct regmap_range tps65912_yes_ranges[] = {
|
||||
regmap_reg_range(TPS65912_INT_STS, TPS65912_GPIO5),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table tps65912_volatile_table = {
|
||||
.yes_ranges = tps65912_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(tps65912_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config tps65912_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_table = &tps65912_volatile_table,
|
||||
};
|
||||
extern const struct regmap_config tps65912_regmap_config;
|
||||
|
||||
int tps65912_device_init(struct tps65912 *tps);
|
||||
int tps65912_device_exit(struct tps65912 *tps);
|
||||
|
Loading…
Reference in New Issue
Block a user