in magnetometer/ak8975.c [878:1018]
static int ak8975_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ak8975_data *data;
struct iio_dev *indio_dev;
struct gpio_desc *eoc_gpiod;
struct gpio_desc *reset_gpiod;
const void *match;
unsigned int i;
int err;
enum asahi_compass_chipset chipset;
const char *name = NULL;
/*
* Grab and set up the supplied GPIO.
* We may not have a GPIO based IRQ to scan, that is fine, we will
* poll if so.
*/
eoc_gpiod = devm_gpiod_get_optional(&client->dev, NULL, GPIOD_IN);
if (IS_ERR(eoc_gpiod))
return PTR_ERR(eoc_gpiod);
if (eoc_gpiod)
gpiod_set_consumer_name(eoc_gpiod, "ak_8975");
/*
* According to AK09911 datasheet, if reset GPIO is provided then
* deassert reset on ak8975_power_on() and assert reset on
* ak8975_power_off().
*/
reset_gpiod = devm_gpiod_get_optional(&client->dev,
"reset", GPIOD_OUT_HIGH);
if (IS_ERR(reset_gpiod))
return PTR_ERR(reset_gpiod);
/* Register with IIO */
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (indio_dev == NULL)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
data->eoc_gpiod = eoc_gpiod;
data->reset_gpiod = reset_gpiod;
data->eoc_irq = 0;
err = iio_read_mount_matrix(&client->dev, &data->orientation);
if (err)
return err;
/* id will be NULL when enumerated via ACPI */
match = device_get_match_data(&client->dev);
if (match) {
chipset = (uintptr_t)match;
name = dev_name(&client->dev);
} else if (id) {
chipset = (enum asahi_compass_chipset)(id->driver_data);
name = id->name;
} else
return -ENOSYS;
for (i = 0; i < ARRAY_SIZE(ak_def_array); i++)
if (ak_def_array[i].type == chipset)
break;
if (i == ARRAY_SIZE(ak_def_array)) {
dev_err(&client->dev, "AKM device type unsupported: %d\n",
chipset);
return -ENODEV;
}
data->def = &ak_def_array[i];
/* 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;
err = ak8975_who_i_am(client, data->def->type);
if (err < 0) {
dev_err(&client->dev, "Unexpected device\n");
goto power_off;
}
dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
/* Perform some basic start-of-day setup of the device. */
err = ak8975_setup(client);
if (err < 0) {
dev_err(&client->dev, "%s initialization fails\n", name);
goto power_off;
}
mutex_init(&data->lock);
indio_dev->channels = ak8975_channels;
indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
indio_dev->info = &ak8975_info;
indio_dev->available_scan_masks = ak8975_scan_masks;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->name = name;
err = iio_triggered_buffer_setup(indio_dev, NULL, ak8975_handle_trigger,
NULL);
if (err) {
dev_err(&client->dev, "triggered buffer setup failed\n");
goto power_off;
}
err = iio_device_register(indio_dev);
if (err) {
dev_err(&client->dev, "device register failed\n");
goto cleanup_buffer;
}
/* Enable runtime PM */
pm_runtime_get_noresume(&client->dev);
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
/*
* The device comes online in 500us, so add two orders of magnitude
* of delay before autosuspending: 50 ms.
*/
pm_runtime_set_autosuspend_delay(&client->dev, 50);
pm_runtime_use_autosuspend(&client->dev);
pm_runtime_put(&client->dev);
return 0;
cleanup_buffer:
iio_triggered_buffer_cleanup(indio_dev);
power_off:
ak8975_power_off(data);
return err;
}