Loading drivers/mfd/qcom-i2c-pmic.c +74 −1 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. */ */ #define pr_fmt(fmt) "I2C PMIC: %s: " fmt, __func__ #define pr_fmt(fmt) "I2C PMIC: %s: " fmt, __func__ Loading Loading @@ -61,6 +61,7 @@ struct i2c_pmic { int summary_irq; int summary_irq; bool resume_completed; bool resume_completed; bool irq_waiting; bool irq_waiting; bool toggle_stat; }; }; static void i2c_pmic_irq_bus_lock(struct irq_data *d) static void i2c_pmic_irq_bus_lock(struct irq_data *d) Loading Loading @@ -473,6 +474,9 @@ static int i2c_pmic_parse_dt(struct i2c_pmic *chip) of_property_read_string(node, "pinctrl-names", &chip->pinctrl_name); of_property_read_string(node, "pinctrl-names", &chip->pinctrl_name); chip->toggle_stat = of_property_read_bool(node, "qcom,enable-toggle-stat"); return rc; return rc; } } Loading Loading @@ -513,6 +517,69 @@ static int i2c_pmic_determine_initial_status(struct i2c_pmic *chip) return 0; return 0; } } #define INT_TEST_OFFSET 0xE0 #define INT_TEST_MODE_EN_BIT BIT(7) #define INT_TEST_VAL_OFFSET 0xE1 #define INT_0_BIT BIT(0) static int i2c_pmic_toggle_stat(struct i2c_pmic *chip) { int rc = 0, i; if (!chip->toggle_stat || !chip->num_periphs) return 0; rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_EN_SET_OFFSET, INT_0_BIT); if (rc < 0) { pr_err("Couldn't write to int_en_set rc=%d\n", rc); return rc; } rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET, INT_TEST_MODE_EN_BIT); if (rc < 0) { pr_err("Couldn't write to int_test rc=%d\n", rc); return rc; } for (i = 0; i < 5; i++) { rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_VAL_OFFSET, INT_0_BIT); if (rc < 0) { pr_err("Couldn't write to int_test_val rc=%d\n", rc); goto exit; } usleep_range(10000, 11000); rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_VAL_OFFSET, 0); if (rc < 0) { pr_err("Couldn't write to int_test_val rc=%d\n", rc); goto exit; } rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_LATCHED_CLR_OFFSET, INT_0_BIT); if (rc < 0) { pr_err("Couldn't write to int_latched_clr rc=%d\n", rc); goto exit; } usleep_range(10000, 11000); } exit: regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET, 0); regmap_write(chip->regmap, chip->periph[0].addr | INT_EN_CLR_OFFSET, INT_0_BIT); return rc; } static struct regmap_config i2c_pmic_regmap_config = { static struct regmap_config i2c_pmic_regmap_config = { .reg_bits = 16, .reg_bits = 16, .val_bits = 8, .val_bits = 8, Loading Loading @@ -571,6 +638,12 @@ static int i2c_pmic_probe(struct i2c_client *client, chip->resume_completed = true; chip->resume_completed = true; mutex_init(&chip->irq_complete); mutex_init(&chip->irq_complete); rc = i2c_pmic_toggle_stat(chip); if (rc < 0) { pr_err("Couldn't toggle stat rc=%d\n", rc); goto cleanup; } rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, i2c_pmic_irq_handler, i2c_pmic_irq_handler, IRQF_ONESHOT | IRQF_SHARED, IRQF_ONESHOT | IRQF_SHARED, Loading Loading
drivers/mfd/qcom-i2c-pmic.c +74 −1 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. */ */ #define pr_fmt(fmt) "I2C PMIC: %s: " fmt, __func__ #define pr_fmt(fmt) "I2C PMIC: %s: " fmt, __func__ Loading Loading @@ -61,6 +61,7 @@ struct i2c_pmic { int summary_irq; int summary_irq; bool resume_completed; bool resume_completed; bool irq_waiting; bool irq_waiting; bool toggle_stat; }; }; static void i2c_pmic_irq_bus_lock(struct irq_data *d) static void i2c_pmic_irq_bus_lock(struct irq_data *d) Loading Loading @@ -473,6 +474,9 @@ static int i2c_pmic_parse_dt(struct i2c_pmic *chip) of_property_read_string(node, "pinctrl-names", &chip->pinctrl_name); of_property_read_string(node, "pinctrl-names", &chip->pinctrl_name); chip->toggle_stat = of_property_read_bool(node, "qcom,enable-toggle-stat"); return rc; return rc; } } Loading Loading @@ -513,6 +517,69 @@ static int i2c_pmic_determine_initial_status(struct i2c_pmic *chip) return 0; return 0; } } #define INT_TEST_OFFSET 0xE0 #define INT_TEST_MODE_EN_BIT BIT(7) #define INT_TEST_VAL_OFFSET 0xE1 #define INT_0_BIT BIT(0) static int i2c_pmic_toggle_stat(struct i2c_pmic *chip) { int rc = 0, i; if (!chip->toggle_stat || !chip->num_periphs) return 0; rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_EN_SET_OFFSET, INT_0_BIT); if (rc < 0) { pr_err("Couldn't write to int_en_set rc=%d\n", rc); return rc; } rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET, INT_TEST_MODE_EN_BIT); if (rc < 0) { pr_err("Couldn't write to int_test rc=%d\n", rc); return rc; } for (i = 0; i < 5; i++) { rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_VAL_OFFSET, INT_0_BIT); if (rc < 0) { pr_err("Couldn't write to int_test_val rc=%d\n", rc); goto exit; } usleep_range(10000, 11000); rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_VAL_OFFSET, 0); if (rc < 0) { pr_err("Couldn't write to int_test_val rc=%d\n", rc); goto exit; } rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_LATCHED_CLR_OFFSET, INT_0_BIT); if (rc < 0) { pr_err("Couldn't write to int_latched_clr rc=%d\n", rc); goto exit; } usleep_range(10000, 11000); } exit: regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET, 0); regmap_write(chip->regmap, chip->periph[0].addr | INT_EN_CLR_OFFSET, INT_0_BIT); return rc; } static struct regmap_config i2c_pmic_regmap_config = { static struct regmap_config i2c_pmic_regmap_config = { .reg_bits = 16, .reg_bits = 16, .val_bits = 8, .val_bits = 8, Loading Loading @@ -571,6 +638,12 @@ static int i2c_pmic_probe(struct i2c_client *client, chip->resume_completed = true; chip->resume_completed = true; mutex_init(&chip->irq_complete); mutex_init(&chip->irq_complete); rc = i2c_pmic_toggle_stat(chip); if (rc < 0) { pr_err("Couldn't toggle stat rc=%d\n", rc); goto cleanup; } rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, i2c_pmic_irq_handler, i2c_pmic_irq_handler, IRQF_ONESHOT | IRQF_SHARED, IRQF_ONESHOT | IRQF_SHARED, Loading