lkml.org 
[lkml]   [2020]   [Aug]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 5/6] at24: Support probing while off
    Date
    In certain use cases (where the chip is part of a camera module, and the
    camera module is wired together with a camera privacy LED), powering on
    the device during probe is undesirable. Add support for the at24 to
    execute probe while being powered off. For this to happen, a hint in form
    of a device property is required from the firmware.

    Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
    ---
    drivers/misc/eeprom/at24.c | 43 +++++++++++++++++++++++---------------
    1 file changed, 26 insertions(+), 17 deletions(-)

    diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
    index 2591c21b2b5d8..a343e55e41126 100644
    --- a/drivers/misc/eeprom/at24.c
    +++ b/drivers/misc/eeprom/at24.c
    @@ -561,6 +561,7 @@ static int at24_probe(struct i2c_client *client)
    bool i2c_fn_i2c, i2c_fn_block;
    unsigned int i, num_addresses;
    struct at24_data *at24;
    + bool low_power;
    struct regmap *regmap;
    bool writable;
    u8 test_byte;
    @@ -698,25 +699,30 @@ static int at24_probe(struct i2c_client *client)

    i2c_set_clientdata(client, at24);

    - err = regulator_enable(at24->vcc_reg);
    - if (err) {
    - dev_err(dev, "Failed to enable vcc regulator\n");
    - return err;
    - }
    + low_power = acpi_dev_state_low_power(&client->dev);
    + if (!low_power) {
    + err = regulator_enable(at24->vcc_reg);
    + if (err) {
    + dev_err(dev, "Failed to enable vcc regulator\n");
    + return err;
    + }

    - /* enable runtime pm */
    - pm_runtime_set_active(dev);
    + pm_runtime_set_active(dev);
    + }
    pm_runtime_enable(dev);

    /*
    - * Perform a one-byte test read to verify that the
    - * chip is functional.
    + * Perform a one-byte test read to verify that the chip is functional,
    + * unless powering on the device is to be avoided during probe (i.e.
    + * it's powered off right now).
    */
    - err = at24_read(at24, 0, &test_byte, 1);
    - if (err) {
    - pm_runtime_disable(dev);
    - regulator_disable(at24->vcc_reg);
    - return -ENODEV;
    + if (!low_power) {
    + err = at24_read(at24, 0, &test_byte, 1);
    + if (err) {
    + pm_runtime_disable(dev);
    + regulator_disable(at24->vcc_reg);
    + return -ENODEV;
    + }
    }

    pm_runtime_idle(dev);
    @@ -736,9 +742,11 @@ static int at24_remove(struct i2c_client *client)
    struct at24_data *at24 = i2c_get_clientdata(client);

    pm_runtime_disable(&client->dev);
    - if (!pm_runtime_status_suspended(&client->dev))
    - regulator_disable(at24->vcc_reg);
    - pm_runtime_set_suspended(&client->dev);
    + if (!acpi_dev_state_low_power(&client->dev)) {
    + if (!pm_runtime_status_suspended(&client->dev))
    + regulator_disable(at24->vcc_reg);
    + pm_runtime_set_suspended(&client->dev);
    + }

    return 0;
    }
    @@ -775,6 +783,7 @@ static struct i2c_driver at24_driver = {
    .probe_new = at24_probe,
    .remove = at24_remove,
    .id_table = at24_ids,
    + .flags = I2C_DRV_FL_ALLOW_LOW_POWER_PROBE,
    };

    static int __init at24_init(void)
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-08-26 13:54    [W:4.060 / U:0.244 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site