Merge tag 'regulator-v5.0' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown: "The biggest chunk of the regulator changes for this release outside of the new drivers is the conversion of the fixed regulator to use the GPIO descriptor API, there's a small addition to the GPIO API plus a bunch of updates to board files to implement it. This is some really welcome work from Linus Walleij that's had a bunch of review and has been sitting in -next for a while so I'm fairly happy there's no major issues. - Helpers for overlapping linear ranges. - Display opmode and consumer requested load in the regualtor_summary file in debugfs, plus a fix there. - Support for the fun and entertaining power off mechanism that the pfuze100 hardware implements. - Conversion of the fixed regulator API to use GPIO descriptors, including pulling in a bunch of patches to a bunch of board files. - New drivers for Cirrus Logic Lochnagar, Qualcomm PMS405, Rohm BD71847, ST PMIC1, and TI LM363x devices" * tag 'regulator-v5.0' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (36 commits) regulator: lochnagar: Use a consisent comment style for SPDX header regulator: bd718x7: Remove struct bd718xx_pmic regulator: Fetch enable gpiods nonexclusive regulator/gpio: Allow nonexclusive GPIO access regulator: lochnagar: Add support for the Cirrus Logic Lochnagar regulator: stpmic1: Return REGULATOR_MODE_INVALID for invalid mode regulator: stpmic1: add stpmic1 regulator driver dt-bindings: regulator: document stpmic1 pmic regulators regulator: axp20x: Mark expected switch fall-throughs regulator: bd718xx: fix build warning on x86_64 regulator: fixed: Default enable high on DT regulators regulator: bd718xx: rename bd71837 to 718xx regulator: bd718XX use pickable ranges regulator/mfd: bd718xx: rename bd71837/bd71847 common instances regulator: Support regulators where voltage ranges are selectable mfd: dt bindings: add BD71847 device-tree binding documentation regulator: dt bindings: add BD71847 device-tree binding documentation regulator/mfd: Support ROHM BD71847 power management IC regulator: da905{2,5}: Remove unnecessary array check regulator: qcom: Add PMS405 regulators ...
This commit is contained in:
@@ -2,26 +2,21 @@
|
||||
//
|
||||
// Copyright (C) 2018 ROHM Semiconductors
|
||||
//
|
||||
// ROHM BD71837MWV PMIC driver
|
||||
// ROHM BD71837MWV and BD71847MWV PMIC driver
|
||||
//
|
||||
// Datasheet available from
|
||||
// Datasheet for BD71837MWV available from
|
||||
// https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
|
||||
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/rohm-bd718x7.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/*
|
||||
* gpio_keys.h requires definiton of bool. It is brought in
|
||||
* by above includes. Keep this as last until gpio_keys.h gets fixed.
|
||||
*/
|
||||
#include <linux/gpio_keys.h>
|
||||
|
||||
static const u8 supported_revisions[] = { 0xA2 /* BD71837 */ };
|
||||
#include <linux/types.h>
|
||||
|
||||
static struct gpio_keys_button button = {
|
||||
.code = KEY_POWER,
|
||||
@@ -35,42 +30,42 @@ static struct gpio_keys_platform_data bd718xx_powerkey_data = {
|
||||
.name = "bd718xx-pwrkey",
|
||||
};
|
||||
|
||||
static struct mfd_cell bd71837_mfd_cells[] = {
|
||||
static struct mfd_cell bd718xx_mfd_cells[] = {
|
||||
{
|
||||
.name = "gpio-keys",
|
||||
.platform_data = &bd718xx_powerkey_data,
|
||||
.pdata_size = sizeof(bd718xx_powerkey_data),
|
||||
},
|
||||
{ .name = "bd71837-clk", },
|
||||
{ .name = "bd71837-pmic", },
|
||||
{ .name = "bd718xx-clk", },
|
||||
{ .name = "bd718xx-pmic", },
|
||||
};
|
||||
|
||||
static const struct regmap_irq bd71837_irqs[] = {
|
||||
REGMAP_IRQ_REG(BD71837_INT_SWRST, 0, BD71837_INT_SWRST_MASK),
|
||||
REGMAP_IRQ_REG(BD71837_INT_PWRBTN_S, 0, BD71837_INT_PWRBTN_S_MASK),
|
||||
REGMAP_IRQ_REG(BD71837_INT_PWRBTN_L, 0, BD71837_INT_PWRBTN_L_MASK),
|
||||
REGMAP_IRQ_REG(BD71837_INT_PWRBTN, 0, BD71837_INT_PWRBTN_MASK),
|
||||
REGMAP_IRQ_REG(BD71837_INT_WDOG, 0, BD71837_INT_WDOG_MASK),
|
||||
REGMAP_IRQ_REG(BD71837_INT_ON_REQ, 0, BD71837_INT_ON_REQ_MASK),
|
||||
REGMAP_IRQ_REG(BD71837_INT_STBY_REQ, 0, BD71837_INT_STBY_REQ_MASK),
|
||||
static const struct regmap_irq bd718xx_irqs[] = {
|
||||
REGMAP_IRQ_REG(BD718XX_INT_SWRST, 0, BD718XX_INT_SWRST_MASK),
|
||||
REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_S, 0, BD718XX_INT_PWRBTN_S_MASK),
|
||||
REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_L, 0, BD718XX_INT_PWRBTN_L_MASK),
|
||||
REGMAP_IRQ_REG(BD718XX_INT_PWRBTN, 0, BD718XX_INT_PWRBTN_MASK),
|
||||
REGMAP_IRQ_REG(BD718XX_INT_WDOG, 0, BD718XX_INT_WDOG_MASK),
|
||||
REGMAP_IRQ_REG(BD718XX_INT_ON_REQ, 0, BD718XX_INT_ON_REQ_MASK),
|
||||
REGMAP_IRQ_REG(BD718XX_INT_STBY_REQ, 0, BD718XX_INT_STBY_REQ_MASK),
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bd71837_irq_chip = {
|
||||
.name = "bd71837-irq",
|
||||
.irqs = bd71837_irqs,
|
||||
.num_irqs = ARRAY_SIZE(bd71837_irqs),
|
||||
static struct regmap_irq_chip bd718xx_irq_chip = {
|
||||
.name = "bd718xx-irq",
|
||||
.irqs = bd718xx_irqs,
|
||||
.num_irqs = ARRAY_SIZE(bd718xx_irqs),
|
||||
.num_regs = 1,
|
||||
.irq_reg_stride = 1,
|
||||
.status_base = BD71837_REG_IRQ,
|
||||
.mask_base = BD71837_REG_MIRQ,
|
||||
.ack_base = BD71837_REG_IRQ,
|
||||
.status_base = BD718XX_REG_IRQ,
|
||||
.mask_base = BD718XX_REG_MIRQ,
|
||||
.ack_base = BD718XX_REG_IRQ,
|
||||
.init_ack_masked = true,
|
||||
.mask_invert = false,
|
||||
};
|
||||
|
||||
static const struct regmap_range pmic_status_range = {
|
||||
.range_min = BD71837_REG_IRQ,
|
||||
.range_max = BD71837_REG_POW_STATE,
|
||||
.range_min = BD718XX_REG_IRQ,
|
||||
.range_max = BD718XX_REG_POW_STATE,
|
||||
};
|
||||
|
||||
static const struct regmap_access_table volatile_regs = {
|
||||
@@ -78,67 +73,53 @@ static const struct regmap_access_table volatile_regs = {
|
||||
.n_yes_ranges = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_config bd71837_regmap_config = {
|
||||
static const struct regmap_config bd718xx_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.volatile_table = &volatile_regs,
|
||||
.max_register = BD71837_MAX_REGISTER - 1,
|
||||
.max_register = BD718XX_MAX_REGISTER - 1,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int bd71837_i2c_probe(struct i2c_client *i2c,
|
||||
static int bd718xx_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct bd71837 *bd71837;
|
||||
int ret, i;
|
||||
unsigned int val;
|
||||
struct bd718xx *bd718xx;
|
||||
int ret;
|
||||
|
||||
bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
|
||||
|
||||
if (!bd71837)
|
||||
return -ENOMEM;
|
||||
|
||||
bd71837->chip_irq = i2c->irq;
|
||||
|
||||
if (!bd71837->chip_irq) {
|
||||
if (!i2c->irq) {
|
||||
dev_err(&i2c->dev, "No IRQ configured\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bd71837->dev = &i2c->dev;
|
||||
dev_set_drvdata(&i2c->dev, bd71837);
|
||||
bd718xx = devm_kzalloc(&i2c->dev, sizeof(struct bd718xx), GFP_KERNEL);
|
||||
|
||||
bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config);
|
||||
if (IS_ERR(bd71837->regmap)) {
|
||||
if (!bd718xx)
|
||||
return -ENOMEM;
|
||||
|
||||
bd718xx->chip_irq = i2c->irq;
|
||||
bd718xx->chip_type = (unsigned int)(uintptr_t)
|
||||
of_device_get_match_data(&i2c->dev);
|
||||
bd718xx->dev = &i2c->dev;
|
||||
dev_set_drvdata(&i2c->dev, bd718xx);
|
||||
|
||||
bd718xx->regmap = devm_regmap_init_i2c(i2c, &bd718xx_regmap_config);
|
||||
if (IS_ERR(bd718xx->regmap)) {
|
||||
dev_err(&i2c->dev, "regmap initialization failed\n");
|
||||
return PTR_ERR(bd71837->regmap);
|
||||
return PTR_ERR(bd718xx->regmap);
|
||||
}
|
||||
|
||||
ret = regmap_read(bd71837->regmap, BD71837_REG_REV, &val);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Read BD71837_REG_DEVICE failed\n");
|
||||
return ret;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(supported_revisions); i++)
|
||||
if (supported_revisions[i] == val)
|
||||
break;
|
||||
|
||||
if (i == ARRAY_SIZE(supported_revisions)) {
|
||||
dev_err(&i2c->dev, "Unsupported chip revision\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = devm_regmap_add_irq_chip(&i2c->dev, bd71837->regmap,
|
||||
bd71837->chip_irq, IRQF_ONESHOT, 0,
|
||||
&bd71837_irq_chip, &bd71837->irq_data);
|
||||
ret = devm_regmap_add_irq_chip(&i2c->dev, bd718xx->regmap,
|
||||
bd718xx->chip_irq, IRQF_ONESHOT, 0,
|
||||
&bd718xx_irq_chip, &bd718xx->irq_data);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Failed to add irq_chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Configure short press to 10 milliseconds */
|
||||
ret = regmap_update_bits(bd71837->regmap,
|
||||
BD71837_REG_PWRONCONFIG0,
|
||||
ret = regmap_update_bits(bd718xx->regmap,
|
||||
BD718XX_REG_PWRONCONFIG0,
|
||||
BD718XX_PWRBTN_PRESS_DURATION_MASK,
|
||||
BD718XX_PWRBTN_SHORT_PRESS_10MS);
|
||||
if (ret) {
|
||||
@@ -148,8 +129,8 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
|
||||
}
|
||||
|
||||
/* Configure long press to 10 seconds */
|
||||
ret = regmap_update_bits(bd71837->regmap,
|
||||
BD71837_REG_PWRONCONFIG1,
|
||||
ret = regmap_update_bits(bd718xx->regmap,
|
||||
BD718XX_REG_PWRONCONFIG1,
|
||||
BD718XX_PWRBTN_PRESS_DURATION_MASK,
|
||||
BD718XX_PWRBTN_LONG_PRESS_10S);
|
||||
|
||||
@@ -159,7 +140,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_irq_get_virq(bd71837->irq_data, BD71837_INT_PWRBTN_S);
|
||||
ret = regmap_irq_get_virq(bd718xx->irq_data, BD718XX_INT_PWRBTN_S);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "Failed to get the IRQ\n");
|
||||
@@ -168,44 +149,51 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
button.irq = ret;
|
||||
|
||||
ret = devm_mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
|
||||
bd71837_mfd_cells,
|
||||
ARRAY_SIZE(bd71837_mfd_cells), NULL, 0,
|
||||
regmap_irq_get_domain(bd71837->irq_data));
|
||||
ret = devm_mfd_add_devices(bd718xx->dev, PLATFORM_DEVID_AUTO,
|
||||
bd718xx_mfd_cells,
|
||||
ARRAY_SIZE(bd718xx_mfd_cells), NULL, 0,
|
||||
regmap_irq_get_domain(bd718xx->irq_data));
|
||||
if (ret)
|
||||
dev_err(&i2c->dev, "Failed to create subdevices\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id bd71837_of_match[] = {
|
||||
{ .compatible = "rohm,bd71837", },
|
||||
static const struct of_device_id bd718xx_of_match[] = {
|
||||
{
|
||||
.compatible = "rohm,bd71837",
|
||||
.data = (void *)BD718XX_TYPE_BD71837,
|
||||
},
|
||||
{
|
||||
.compatible = "rohm,bd71847",
|
||||
.data = (void *)BD718XX_TYPE_BD71847,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bd71837_of_match);
|
||||
MODULE_DEVICE_TABLE(of, bd718xx_of_match);
|
||||
|
||||
static struct i2c_driver bd71837_i2c_driver = {
|
||||
static struct i2c_driver bd718xx_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rohm-bd718x7",
|
||||
.of_match_table = bd71837_of_match,
|
||||
.of_match_table = bd718xx_of_match,
|
||||
},
|
||||
.probe = bd71837_i2c_probe,
|
||||
.probe = bd718xx_i2c_probe,
|
||||
};
|
||||
|
||||
static int __init bd71837_i2c_init(void)
|
||||
static int __init bd718xx_i2c_init(void)
|
||||
{
|
||||
return i2c_add_driver(&bd71837_i2c_driver);
|
||||
return i2c_add_driver(&bd718xx_i2c_driver);
|
||||
}
|
||||
|
||||
/* Initialise early so consumer devices can complete system boot */
|
||||
subsys_initcall(bd71837_i2c_init);
|
||||
subsys_initcall(bd718xx_i2c_init);
|
||||
|
||||
static void __exit bd71837_i2c_exit(void)
|
||||
static void __exit bd718xx_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&bd71837_i2c_driver);
|
||||
i2c_del_driver(&bd718xx_i2c_driver);
|
||||
}
|
||||
module_exit(bd71837_i2c_exit);
|
||||
module_exit(bd718xx_i2c_exit);
|
||||
|
||||
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
|
||||
MODULE_DESCRIPTION("ROHM BD71837 Power Management IC driver");
|
||||
MODULE_DESCRIPTION("ROHM BD71837/BD71847 Power Management IC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
Reference in New Issue
Block a user