iio: magn: ak8975: allow a delay after enabling regulators
[cascardo/linux.git] / drivers / iio / magnetometer / ak8975.c
index 609a2c4..bf3ffc4 100644 (file)
@@ -379,37 +379,40 @@ struct ak8975_data {
        u8                      cntl_cache;
        struct iio_mount_matrix orientation;
        struct regulator        *vdd;
+       struct regulator        *vid;
 };
 
 /* Enable attached power regulator if any. */
-static int ak8975_power_on(struct i2c_client *client)
+static int ak8975_power_on(const struct ak8975_data *data)
 {
-       const struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct ak8975_data *data = iio_priv(indio_dev);
        int ret;
 
-       data->vdd = devm_regulator_get(&client->dev, "vdd");
-       if (IS_ERR_OR_NULL(data->vdd)) {
-               ret = PTR_ERR(data->vdd);
-               if (ret == -ENODEV)
-                       ret = 0;
-       } else {
-               ret = regulator_enable(data->vdd);
+       ret = regulator_enable(data->vdd);
+       if (ret) {
+               dev_warn(&data->client->dev,
+                        "Failed to enable specified Vdd supply\n");
+               return ret;
        }
-
-       if (ret)
-               dev_err(&client->dev, "failed to enable Vdd supply: %d\n", ret);
-       return ret;
+       ret = regulator_enable(data->vid);
+       if (ret) {
+               dev_warn(&data->client->dev,
+                        "Failed to enable specified Vid supply\n");
+               return ret;
+       }
+       /*
+        * According to the datasheet the power supply rise time i 200us
+        * and the minimum wait time before mode setting is 100us, in
+        * total 300 us. Add some margin and say minimum 500us here.
+        */
+       usleep_range(500, 1000);
+       return 0;
 }
 
 /* Disable attached power regulator if any. */
-static void ak8975_power_off(const struct i2c_client *client)
+static void ak8975_power_off(const struct ak8975_data *data)
 {
-       const struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       const struct ak8975_data *data = iio_priv(indio_dev);
-
-       if (!IS_ERR_OR_NULL(data->vdd))
-               regulator_disable(data->vdd);
+       regulator_disable(data->vid);
+       regulator_disable(data->vdd);
 }
 
 /*
@@ -430,8 +433,8 @@ static int ak8975_who_i_am(struct i2c_client *client,
         * AK8975   |  DEVICE_ID |  NA
         * AK8963   |  DEVICE_ID |  NA
         */
-       ret = i2c_smbus_read_i2c_block_data(client, AK09912_REG_WIA1,
-                                           2, wia_val);
+       ret = i2c_smbus_read_i2c_block_data_or_emulated(
+                       client, AK09912_REG_WIA1, 2, wia_val);
        if (ret < 0) {
                dev_err(&client->dev, "Error reading WIA\n");
                return ret;
@@ -543,9 +546,9 @@ static int ak8975_setup(struct i2c_client *client)
        }
 
        /* Get asa data and store in the device data. */
-       ret = i2c_smbus_read_i2c_block_data(client,
-                                           data->def->ctrl_regs[ASA_BASE],
-                                           3, data->asa);
+       ret = i2c_smbus_read_i2c_block_data_or_emulated(
+                       client, data->def->ctrl_regs[ASA_BASE],
+                       3, data->asa);
        if (ret < 0) {
                dev_err(&client->dev, "Not able to read asa data\n");
                return ret;
@@ -686,6 +689,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
        struct ak8975_data *data = iio_priv(indio_dev);
        const struct i2c_client *client = data->client;
        const struct ak_def *def = data->def;
+       u16 buff;
        int ret;
 
        mutex_lock(&data->lock);
@@ -694,14 +698,17 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
        if (ret)
                goto exit;
 
-       ret = i2c_smbus_read_word_data(client, def->data_regs[index]);
+       ret = i2c_smbus_read_i2c_block_data_or_emulated(
+                       client, def->data_regs[index],
+                       sizeof(buff), (u8*)&buff);
        if (ret < 0)
                goto exit;
 
        mutex_unlock(&data->lock);
 
-       /* Clamp to valid range. */
-       *val = clamp_t(s16, ret, -def->range, def->range);
+       /* Swap bytes and convert to valid range. */
+       buff = le16_to_cpu(buff);
+       *val = clamp_t(s16, buff, -def->range, def->range);
        return IIO_VAL_INT;
 
 exit:
@@ -825,7 +832,8 @@ static void ak8975_fill_buffer(struct iio_dev *indio_dev)
        buff[1] = clamp_t(s16, le16_to_cpu(buff[1]), -def->range, def->range);
        buff[2] = clamp_t(s16, le16_to_cpu(buff[2]), -def->range, def->range);
 
-       iio_push_to_buffers_with_timestamp(indio_dev, buff, iio_get_time_ns());
+       iio_push_to_buffers_with_timestamp(indio_dev, buff,
+                                          iio_get_time_ns(indio_dev));
        return;
 
 unlock:
@@ -919,7 +927,15 @@ static int ak8975_probe(struct i2c_client *client,
 
        data->def = &ak_def_array[chipset];
 
-       err = ak8975_power_on(client);
+       /* Fetch the regulators */
+       data->vdd = devm_regulator_get(&client->dev, "vdd");
+       if (IS_ERR(data->vdd))
+               return PTR_ERR(data->vdd);
+       data->vid = devm_regulator_get(&client->dev, "vid");
+       if (IS_ERR(data->vid))
+               return PTR_ERR(data->vid);
+
+       err = ak8975_power_on(data);
        if (err)
                return err;
 
@@ -964,17 +980,18 @@ static int ak8975_probe(struct i2c_client *client,
 cleanup_buffer:
        iio_triggered_buffer_cleanup(indio_dev);
 power_off:
-       ak8975_power_off(client);
+       ak8975_power_off(data);
        return err;
 }
 
 static int ak8975_remove(struct i2c_client *client)
 {
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct ak8975_data *data = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
        iio_triggered_buffer_cleanup(indio_dev);
-       ak8975_power_off(client);
+       ak8975_power_off(data);
 
        return 0;
 }