Hello, I tried to patch my kernel to load the axp20x driver to control the axp152 chip.
The power key works and I can power off the system. However, on next power on the system would power off again when the ehci or ohci controller is probed. I disabled the controllers and everything appears to work OK otherwise. Anyone has any idea why probing the USB controller would upset the axp? I disabled the regulator part of the mfd so regulators should presumably not get triggered. Thanks Michal diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt index 98685f2..7bbd8e9 100644 --- a/Documentation/devicetree/bindings/mfd/axp20x.txt +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt @@ -1,11 +1,12 @@ -AXP202/AXP209 device tree bindings +AXP152/AXP202/AXP209 device tree bindings The axp20x family current members : +axp152 (X-Powers) axp202 (X-Powers) axp209 (X-Powers) Required properties: -- compatible: "x-powers,axp202" or "x-powers,axp209" +- compatible: "x-powers,axp152", "x-powers,axp202" or "x-powers,axp209" - reg: The I2C slave address for the AXP chip - interrupt-parent: The parent interrupt controller - interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin diff --git a/arch/arm/boot/dts/axp152.dtsi b/arch/arm/boot/dts/axp152.dtsi new file mode 100644 index 0000000..fe2dc01 --- /dev/null +++ b/arch/arm/boot/dts/axp152.dtsi @@ -0,0 +1,93 @@ +/* + * Copyright 2015 Chen-Yu Tsai + * + * Chen-Yu Tsai <[email protected]> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * AXP202/209 Integrated Power Management Chip + * http://www.x-powers.com/product/AXP20X.php + * http://dl.linux-sunxi.org/AXP/AXP209%20Datasheet%20v1.0_cn.pdf + */ + +&axp152 { + compatible = "x-powers,axp152"; + interrupt-controller; + #interrupt-cells = <1>; + + regulators { + /* Default work frequency for buck regulators */ + /* FIXME update regulators for AXP152 defaults */ + x-powers,dcdc-freq = <1500>; + + reg_dcdc2: dcdc2 { + regulator-name = "dcdc2"; + }; + + reg_dcdc3: dcdc3 { + regulator-name = "dcdc3"; + }; + + reg_ldo1: ldo1 { + /* LDO1 is a fixed output regulator */ + regulator-always-on; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + regulator-name = "ldo1"; + }; + + reg_ldo2: ldo2 { + regulator-name = "ldo2"; + }; + + reg_ldo3: ldo3 { + regulator-name = "ldo3"; + }; + + reg_ldo4: ldo4 { + regulator-name = "ldo4"; + }; + + reg_ldo5: ldo5 { + regulator-name = "ldo5"; + }; + }; +}; diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts index 7c1bc57..b75b922 100644 --- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts +++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts @@ -87,7 +87,7 @@ }; &ehci0 { - status = "okay"; + //status = "okay"; }; &emac { @@ -105,6 +105,11 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; status = "okay"; + + axp152: pmic@30 { + reg = <0x30>; + interrupts = <0>; + }; }; &i2c1 { @@ -201,7 +206,7 @@ }; &ohci0 { - status = "okay"; + //status = "okay"; }; &otg_sram { @@ -259,6 +264,8 @@ }; }; +#include "axp152.dtsi" + ®_usb0_vbus { pinctrl-0 = <&usb0_vbus_pin_olinuxino_m>; gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */ diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index d18029b..8835716 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -30,6 +30,7 @@ #define AXP20X_OFF 0x80 static const char * const axp20x_model_names[] = { + "AXP152", "AXP202", "AXP209", "AXP288", @@ -73,6 +74,20 @@ static const struct regmap_access_table axp288_volatile_table = { .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges), }; +static struct resource axp152_pek_resources[] = { + { + .name = "PEK_DBR", + .start = AXP152_IRQ_PEK_RIS_EDGE, + .end = AXP152_IRQ_PEK_RIS_EDGE, + .flags = IORESOURCE_IRQ, + }, { + .name = "PEK_DBF", + .start = AXP152_IRQ_PEK_FAL_EDGE, + .end = AXP152_IRQ_PEK_FAL_EDGE, + .flags = IORESOURCE_IRQ, + }, +}; + static struct resource axp20x_pek_resources[] = { { .name = "PEK_DBR", @@ -140,6 +155,25 @@ static const struct regmap_config axp288_regmap_config = { #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \ [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } +static const struct regmap_irq axp152_regmap_irqs[] = { + INIT_REGMAP_IRQ(AXP152, ACIN_PLUGIN, 0, 6), + INIT_REGMAP_IRQ(AXP152, ACIN_REMOVAL, 0, 5), + INIT_REGMAP_IRQ(AXP152, VBUS_PLUGIN, 0, 3), + INIT_REGMAP_IRQ(AXP152, VBUS_REMOVAL, 0, 2), + INIT_REGMAP_IRQ(AXP152, DCDC1_V_LOW, 1, 5), + INIT_REGMAP_IRQ(AXP152, DCDC2_V_LOW, 1, 4), + INIT_REGMAP_IRQ(AXP152, DCDC3_V_LOW, 1, 3), + INIT_REGMAP_IRQ(AXP152, DCDC4_V_LOW, 1, 2), + INIT_REGMAP_IRQ(AXP152, PEK_SHORT, 1, 1), + INIT_REGMAP_IRQ(AXP152, PEK_LONG, 1, 0), + INIT_REGMAP_IRQ(AXP152, TIMER, 2, 7), + INIT_REGMAP_IRQ(AXP152, PEK_RIS_EDGE, 2, 6), + INIT_REGMAP_IRQ(AXP152, PEK_FAL_EDGE, 2, 5), + INIT_REGMAP_IRQ(AXP152, GPIO3_INPUT, 2, 3), + INIT_REGMAP_IRQ(AXP152, GPIO2_INPUT, 2, 2), + INIT_REGMAP_IRQ(AXP152, GPIO1_INPUT, 2, 1), + INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0), +}; static const struct regmap_irq axp20x_regmap_irqs[] = { INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7), @@ -222,6 +256,7 @@ static const struct regmap_irq axp288_regmap_irqs[] = { }; static const struct of_device_id axp20x_of_match[] = { + { .compatible = "x-powers,axp152", .data = (void *) AXP152_ID }, { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID }, { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID }, { }, @@ -245,6 +280,18 @@ static const struct acpi_device_id axp20x_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, axp20x_acpi_match); +static const struct regmap_irq_chip axp152_regmap_irq_chip = { + .name = "axp152_irq_chip", + .status_base = AXP20X_IRQ1_STATE, + .ack_base = AXP20X_IRQ1_STATE, + .mask_base = AXP20X_IRQ1_EN, + .mask_invert = true, + .init_ack_masked = true, + .irqs = axp152_regmap_irqs, + .num_irqs = ARRAY_SIZE(axp152_regmap_irqs), + .num_regs = 3, +}; + static const struct regmap_irq_chip axp20x_regmap_irq_chip = { .name = "axp20x_irq_chip", .status_base = AXP20X_IRQ1_STATE, @@ -281,6 +328,16 @@ static struct mfd_cell axp20x_cells[] = { }, }; +static struct mfd_cell axp152_cells[] = { + { + .name = "axp20x-pek", + .num_resources = ARRAY_SIZE(axp152_pek_resources), + .resources = axp152_pek_resources, + }, { + .name = "axp20x-regulator", + }, +}; + static struct resource axp288_adc_resources[] = { { .name = "GPADC", @@ -419,6 +476,12 @@ static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev) } switch (axp20x->variant) { + case AXP152_ID: + axp20x->nr_cells = ARRAY_SIZE(axp152_cells); + axp20x->cells = axp152_cells; + axp20x->regmap_cfg = &axp20x_regmap_config; + axp20x->regmap_irq_chip = &axp152_regmap_irq_chip; + break; case AXP202_ID: case AXP209_ID: axp20x->nr_cells = ARRAY_SIZE(axp20x_cells); diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 0d309a0..db61fa8 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -859,7 +859,7 @@ static int emac_probe(struct platform_device *pdev) clk_prepare_enable(db->clk); - ret = sunxi_sram_claim(SUNXI_SRAM_EMAC, "emac"); + ret = sunxi_sram_claim(&pdev->dev); if (ret) dev_warn(&pdev->dev, "Couldn't map SRAM to device\n"); @@ -908,7 +908,7 @@ static int emac_probe(struct platform_device *pdev) return 0; out_release_sram: - sunxi_sram_release(SUNXI_SRAM_EMAC); + sunxi_sram_release(&pdev->dev); out: dev_err(db->dev, "not found (%d).\n", ret); @@ -922,7 +922,7 @@ static int emac_remove(struct platform_device *pdev) struct net_device *ndev = platform_get_drvdata(pdev); unregister_netdev(ndev); - sunxi_sram_release(SUNXI_SRAM_EMAC); + sunxi_sram_release(&pdev->dev); free_netdev(ndev); dev_dbg(&pdev->dev, "released and freed device\n"); diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index e4331f5..b5cddb1 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -148,7 +148,7 @@ static const struct regulator_desc axp20x_regulators[] = { AXP20X_DESC_TABLE(LDO4, "ldo4", "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08), AXP20X_DESC_IO(LDO5, "ldo5", "ldo5in", 1800, 3300, 100, - AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07, + AXP20X_LDOGPIO0_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED, AXP20X_IO_DISABLED), }; @@ -229,6 +229,11 @@ static int axp20x_regulator_probe(struct platform_device *pdev) /* This only sets the dcdc freq. Ignore any errors */ axp20x_regulator_parse_dt(pdev); + if (axp20x->variant == AXP152_ID) { + dev_warn(&pdev->dev, "axp152 regulator not yet supported"); + return -ENOSYS; + } + for (i = 0; i < AXP20X_REG_ID_MAX; i++) { rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i], &config); diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index dfabd6d..20542af 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -12,7 +12,8 @@ #define __LINUX_MFD_AXP20X_H enum { - AXP202_ID = 0, + AXP152_ID = 0, + AXP202_ID, AXP209_ID, AXP288_ID, NR_AXP20X_VARIANTS, @@ -24,12 +25,23 @@ enum { #define AXP20X_PWR_INPUT_STATUS 0x00 #define AXP20X_PWR_OP_MODE 0x01 #define AXP20X_USB_OTG_STATUS 0x02 +#define AXP20X_IC_TYPE 0x03 #define AXP20X_PWR_OUT_CTRL 0x12 +#define AXP152_LDO3456_DC1234_CTRL 0x12 +#define AXP152_LDO0_V_OUT 0x15 +#define AXP152_LDO0_CTRL 0x15 #define AXP20X_DCDC2_V_OUT 0x23 +#define AXP152_DCDC2_V_OUT 0x23 #define AXP20X_DCDC2_LDO3_V_SCAL 0x25 +#define AXP152_DCDC1_V_OUT 0x26 #define AXP20X_DCDC3_V_OUT 0x27 +#define AXP152_DCDC3_V_OUT 0x27 #define AXP20X_LDO24_V_OUT 0x28 +#define AXP152_LDO34_V_OUT 0x28 #define AXP20X_LDO3_V_OUT 0x29 +#define AXP152_LDO5_V_OUT 0x29 +#define AXP152_LDO6_V_OUT 0x2a +#define AXP152_DCDC4_V_OUT 0x2b #define AXP20X_VBUS_IPSOUT_MGMT 0x30 #define AXP20X_V_OFF 0x31 #define AXP20X_OFF_CTRL 0x32 @@ -45,7 +57,7 @@ enum { #define AXP20X_V_LTF_DISCHRG 0x3c #define AXP20X_V_HTF_DISCHRG 0x3d -/* Interrupt */ +/* Interrupt - only 3 on AXP15*/ #define AXP20X_IRQ1_EN 0x40 #define AXP20X_IRQ2_EN 0x41 #define AXP20X_IRQ3_EN 0x42 @@ -102,11 +114,18 @@ enum { /* GPIO */ #define AXP20X_GPIO0_CTRL 0x90 -#define AXP20X_LDO5_V_OUT 0x91 +#define AXP152_GPIO0_CTRL 0x90 +#define AXP20X_LDOGPIO0_V_OUT 0x91 +#define AXP152_GPIO1_CTRL 0x91 #define AXP20X_GPIO1_CTRL 0x92 +#define AXP152_GPIO2_CTRL 0x92 #define AXP20X_GPIO2_CTRL 0x93 +#define AXP152_GPIO3_CTRL 0x93 #define AXP20X_GPIO20_SS 0x94 +#define AXP152_GPIO012_SS 0x94 #define AXP20X_GPIO3_CTRL 0x95 +#define AXP152_LDOGPIO0_V_OUT 0x96 +#define AXP152_GPIO0123_SS 0x97 /* Battery */ #define AXP20X_CHRG_CC_31_24 0xb0 @@ -159,7 +178,7 @@ enum { }; /* IRQs */ -enum { +enum axp20x_irqs { AXP20X_IRQ_ACIN_OVER_V = 1, AXP20X_IRQ_ACIN_PLUGIN, AXP20X_IRQ_ACIN_REMOVAL, @@ -193,12 +212,34 @@ enum { AXP20X_IRQ_TIMER, AXP20X_IRQ_PEK_RIS_EDGE, AXP20X_IRQ_PEK_FAL_EDGE, + AXP20X_dummy, AXP20X_IRQ_GPIO3_INPUT, AXP20X_IRQ_GPIO2_INPUT, AXP20X_IRQ_GPIO1_INPUT, AXP20X_IRQ_GPIO0_INPUT, }; +enum axp152_irqs { + AXP152_IRQ_ACIN_PLUGIN = 2, + AXP152_IRQ_ACIN_REMOVAL, + AXP152_IRQ_VBUS_PLUGIN = 5, + AXP152_IRQ_VBUS_REMOVAL, + AXP152_IRQ_DCDC1_V_LOW = 10, + AXP152_IRQ_DCDC2_V_LOW, + AXP152_IRQ_DCDC3_V_LOW, + AXP152_IRQ_DCDC4_V_LOW, + AXP152_IRQ_PEK_SHORT = 14, + AXP152_IRQ_PEK_LONG, + AXP152_IRQ_TIMER, + AXP152_IRQ_PEK_RIS_EDGE, + AXP152_IRQ_PEK_FAL_EDGE, + AXP152_dummy, + AXP152_IRQ_GPIO3_INPUT, + AXP152_IRQ_GPIO2_INPUT, + AXP152_IRQ_GPIO1_INPUT, + AXP152_IRQ_GPIO0_INPUT, +}; + enum axp288_irqs { AXP288_IRQ_VBUS_FALL = 2, AXP288_IRQ_VBUS_RISE, -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
