aboutsummaryrefslogtreecommitdiff
path: root/drivers/iio/magnetometer/ak8975.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-04 12:31:05 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-04 12:31:05 -0700
commiteb7bfed901b9fea6e48bec10009dc8c8641e36e7 (patch)
treee03df0b64ecdfc3c51bf0bbdd2f96cd2a6348a7a /drivers/iio/magnetometer/ak8975.c
parent56d118c243fbc62d95a79183bb6bcfc38a398da5 (diff)
parent486294f184c05cff116160bb731cbb679f047621 (diff)
Merge tag 'iio-for-4.7a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: First round of IIO new device support, features and cleanups for the 4.7 cycle. New core support * UV light modifier (for intensity) * UV light index channel type. New device support * hp206c barometer and altimeter - new driver. * mcp4131 potentiometer - new driver supporting lots of parts from Microchip. * mma8452 - FXLS8471Q support - NXP LPC18XX SOC ADC - new driver. - NXP LPC18XX SOC DAC - new driver. - rockchip_saradc - support rk3399 * st accel - h3lis331dl support Staging driver removals * adis16204 - obsolete part making it hard to get parts to test the driver in order to clean it up. * adis16220 - obsolete part making it hard to get the parts test the driver in order to clean it up. Features * core - convenience functions to claim / release direct access to the device. Makes more consistent handling of this corner easier. Used in ad7192 driver. * ak8975 - power regulator support. * at91-sama5d2 - differential channel support. * mma8452 - runtime pm support - drop device specific autosleep and use the runtime pm one instead. * ms5611 - DT bindings - oversampling ratio support Cleanups and minor fixes * MAINTAINERS - Peter got married - hence name change! * Documentation - Fix a typo in in_proximity_raw description. - Add some missing docs for iio_buffer_access_funcs. * Tools - update iio_event_monitor names to match new stuff. - make generic_buffer look for triggers ending in -trigger as we let these in for a number of drivers a long time back and now it is a fairly common option. Drivers * staging wide - convert bare unsigned usage to unsigned int to comply with coding style. * non staging wide: - since boiler plate gpio handling of interrupts has been moved into the ACPI core we don't need to include gpio/consumer.h in a load of drivers so drop it. * ad7606 - fix an endian casting sparse warning. * ak8975 - fix a possible unitialized warning from gcc. - drop and unused field left over from earlier cleanups - fix a missing regulator_disable on exit. * at91-sama5d2 - typo and indentation - missing IOMEM dependency. - cleanup mode register usage by avoidling erasing whole thing when changing the sampling frequency. * bmc150 - use the core demux and available_scan_masks to simplify buffer handling - optimize the transfers in the trigger handler now we have a magic function to emulate bulk reads (under circumstances met here). This matters with some rather dumb i2c adapters in particular. - use a single regmap_conf for all bus types as they were all the same. * bmg160 - use the core demux and available_scan_masks to simplify the buffer handling - optimize the transfers in the trigger handler now we have a magic funciton to emulate bulk rads (under circumstances met here). - drop gpio interrupt probing from the driver (ACPI) as now handled by the ACPI core. * ina2xx-adc - update the CALIB register when RShunt changes. - fix scale for VShunt - in reality this error canceled out when used. * isl29028 - use regmap to retrieve the struct device instead of carrying a second copy of it around. * kxcjk-1013 - use core demux - optimize i2c transfers in the trigger handler. * mcp4531 - refactor to use a pointer to access model parameters instead of indexing into the array each time. * mma8452 - style fixes - avoid swtiching to active whenever the config changes - add missin i2c_device_id for mma8451 * mpu6050 - fix possible NULL dereference. - fix the name / chip_id used when ACPI used (otherwise reports as NULL). * ms5611 - fix a missing regulator_disable that left the regulator on during removal. * mxc4005 - drop gpio interrupt handling for ACPI case from driver as the core now handles this case. * st-sensors - note that there are only ever a maximum of 3 axis on current st-sensors so just allocate a fixed sized buffer big enough for that. * tpl0102 - change the i2c_check_functionality condition to bring it inline with other IIO users as EOPNOTSUPP. * tsl2563 - replace deprecated flush_scheduled_work
Diffstat (limited to 'drivers/iio/magnetometer/ak8975.c')
-rw-r--r--drivers/iio/magnetometer/ak8975.c70
1 files changed, 65 insertions, 5 deletions
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index 9c5c9ef3f1da..48d127a45d90 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -32,6 +32,7 @@
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/acpi.h>
+#include <linux/regulator/consumer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -361,7 +362,6 @@ static const struct ak_def ak_def_array[AK_MAX_TYPE] = {
struct ak8975_data {
struct i2c_client *client;
const struct ak_def *def;
- struct attribute_group attrs;
struct mutex lock;
u8 asa[3];
long raw_to_gauss[3];
@@ -370,8 +370,40 @@ struct ak8975_data {
wait_queue_head_t data_ready_queue;
unsigned long flags;
u8 cntl_cache;
+ struct regulator *vdd;
};
+/* Enable attached power regulator if any. */
+static int ak8975_power_on(struct i2c_client *client)
+{
+ 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);
+ }
+
+ if (ret)
+ dev_err(&client->dev, "failed to enable Vdd supply: %d\n", ret);
+ return ret;
+}
+
+/* Disable attached power regulator if any. */
+static void ak8975_power_off(const struct i2c_client *client)
+{
+ 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);
+}
+
/*
* Return 0 if the i2c device is the one we expect.
* return a negative error number otherwise
@@ -774,8 +806,11 @@ static int ak8975_probe(struct i2c_client *client,
if (id) {
chipset = (enum asahi_compass_chipset)(id->driver_data);
name = id->name;
- } else if (ACPI_HANDLE(&client->dev))
+ } else if (ACPI_HANDLE(&client->dev)) {
name = ak8975_match_acpi_device(&client->dev, &chipset);
+ if (!name)
+ return -ENODEV;
+ }
else
return -ENOSYS;
@@ -786,10 +821,15 @@ static int ak8975_probe(struct i2c_client *client,
}
data->def = &ak_def_array[chipset];
+
+ err = ak8975_power_on(client);
+ if (err)
+ return err;
+
err = ak8975_who_i_am(client, data->def->type);
if (err < 0) {
dev_err(&client->dev, "Unexpected device\n");
- return err;
+ goto power_off;
}
dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
@@ -797,7 +837,7 @@ static int ak8975_probe(struct i2c_client *client,
err = ak8975_setup(client);
if (err < 0) {
dev_err(&client->dev, "%s initialization fails\n", name);
- return err;
+ goto power_off;
}
mutex_init(&data->lock);
@@ -807,7 +847,26 @@ static int ak8975_probe(struct i2c_client *client,
indio_dev->info = &ak8975_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->name = name;
- return devm_iio_device_register(&client->dev, indio_dev);
+
+ err = iio_device_register(indio_dev);
+ if (err)
+ goto power_off;
+
+ return 0;
+
+power_off:
+ ak8975_power_off(client);
+ return err;
+}
+
+static int ak8975_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+ ak8975_power_off(client);
+
+ return 0;
}
static const struct i2c_device_id ak8975_id[] = {
@@ -841,6 +900,7 @@ static struct i2c_driver ak8975_driver = {
.acpi_match_table = ACPI_PTR(ak_acpi_match),
},
.probe = ak8975_probe,
+ .remove = ak8975_remove,
.id_table = ak8975_id,
};
module_i2c_driver(ak8975_driver);