static int ak89xx_power_supply(struct inv_ak89xx_state_s *st, bool on)
{
	int rc;
	dev_dbg(&st->i2c->dev, "%s: on=%d\n", __func__, on);
	if (on) {
		if (st->plat_data.power_supply) {
			rc = st->plat_data.power_supply(&st->i2c->dev, 1);
			if (!rc)
				rc = ak89xx_init(st);
		} else {
			rc = 0;
		}
	} else {
		if (st->plat_data.power_supply)
			rc = st->plat_data.power_supply(&st->i2c->dev, 0);
		else
			rc = 0;
	}
	return rc;
}
Ejemplo n.º 2
0
/**
 *  inv_ak89xx_probe() - probe function.
 */
static int inv_ak89xx_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct inv_ak89xx_state_s *st;
	struct iio_dev *indio_dev;
	int result;
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		result = -ENODEV;
		goto out_no_free;
	}
	indio_dev = iio_allocate_device(sizeof(*st));
	if (indio_dev == NULL) {
		result =  -ENOMEM;
		goto out_no_free;
	}
	st = iio_priv(indio_dev);
	st->i2c = client;
	st->sl_handle = client->adapter;
	st->plat_data =
		*(struct mpu_platform_data *)dev_get_platdata(&client->dev);
	st->i2c_addr = client->addr;
	st->delay = AK89XX_DEFAULT_DELAY;
	st->compass_id = id->driver_data;
	st->compass_scale = 0;

	i2c_set_clientdata(client, indio_dev);
	result = ak89xx_init(st);
	if (result)
		goto out_free;

	indio_dev->dev.parent = &client->dev;
	indio_dev->name = id->name;
	indio_dev->channels = compass_channels;
	indio_dev->num_channels = ARRAY_SIZE(compass_channels);
	indio_dev->info = &ak89xx_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->currentmode = INDIO_DIRECT_MODE;

	result = inv_ak89xx_configure_ring(indio_dev);
	if (result)
		goto out_free;
	result = iio_buffer_register(indio_dev, indio_dev->channels,
					indio_dev->num_channels);
	if (result)
		goto out_unreg_ring;
	result = inv_ak89xx_probe_trigger(indio_dev);
	if (result)
		goto out_remove_ring;

	result = iio_device_register(indio_dev);
	if (result)
		goto out_remove_trigger;
	INIT_DELAYED_WORK(&st->work, ak89xx_work_func);
	pr_info("%s: Probe name %s\n", __func__, id->name);
	return 0;
out_remove_trigger:
	if (indio_dev->modes & INDIO_BUFFER_TRIGGERED)
		inv_ak89xx_remove_trigger(indio_dev);
out_remove_ring:
	iio_buffer_unregister(indio_dev);
out_unreg_ring:
	inv_ak89xx_unconfigure_ring(indio_dev);
out_free:
	iio_free_device(indio_dev);
out_no_free:
	dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result);
	return -EIO;
}