static int ak8974_probe()

in magnetometer/ak8974.c [817:970]


static int ak8974_probe(struct i2c_client *i2c,
			const struct i2c_device_id *id)
{
	struct iio_dev *indio_dev;
	struct ak8974 *ak8974;
	unsigned long irq_trig;
	int irq = i2c->irq;
	int ret;

	/* Register with IIO */
	indio_dev = devm_iio_device_alloc(&i2c->dev, sizeof(*ak8974));
	if (indio_dev == NULL)
		return -ENOMEM;

	ak8974 = iio_priv(indio_dev);
	i2c_set_clientdata(i2c, indio_dev);
	ak8974->i2c = i2c;
	mutex_init(&ak8974->lock);

	ret = iio_read_mount_matrix(&i2c->dev, &ak8974->orientation);
	if (ret)
		return ret;

	ak8974->regs[0].supply = ak8974_reg_avdd;
	ak8974->regs[1].supply = ak8974_reg_dvdd;

	ret = devm_regulator_bulk_get(&i2c->dev,
				      ARRAY_SIZE(ak8974->regs),
				      ak8974->regs);
	if (ret < 0)
		return dev_err_probe(&i2c->dev, ret, "cannot get regulators\n");

	ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
	if (ret < 0) {
		dev_err(&i2c->dev, "cannot enable regulators\n");
		return ret;
	}

	/* Take runtime PM online */
	pm_runtime_get_noresume(&i2c->dev);
	pm_runtime_set_active(&i2c->dev);
	pm_runtime_enable(&i2c->dev);

	ak8974->map = devm_regmap_init_i2c(i2c, &ak8974_regmap_config);
	if (IS_ERR(ak8974->map)) {
		dev_err(&i2c->dev, "failed to allocate register map\n");
		pm_runtime_put_noidle(&i2c->dev);
		pm_runtime_disable(&i2c->dev);
		return PTR_ERR(ak8974->map);
	}

	ret = ak8974_set_power(ak8974, AK8974_PWR_ON);
	if (ret) {
		dev_err(&i2c->dev, "could not power on\n");
		goto disable_pm;
	}

	ret = ak8974_detect(ak8974);
	if (ret) {
		dev_err(&i2c->dev, "neither AK8974 nor AMI30x found\n");
		goto disable_pm;
	}

	ret = ak8974_selftest(ak8974);
	if (ret)
		dev_err(&i2c->dev, "selftest failed (continuing anyway)\n");

	ret = ak8974_reset(ak8974);
	if (ret) {
		dev_err(&i2c->dev, "AK8974 reset failed\n");
		goto disable_pm;
	}

	switch (ak8974->variant) {
	case AK8974_WHOAMI_VALUE_AMI306:
	case AK8974_WHOAMI_VALUE_AMI305:
		indio_dev->channels = ak8974_12_bits_channels;
		indio_dev->num_channels = ARRAY_SIZE(ak8974_12_bits_channels);
		break;
	case AK8974_WHOAMI_VALUE_HSCDTD008A:
		indio_dev->channels = ak8974_15_bits_channels;
		indio_dev->num_channels = ARRAY_SIZE(ak8974_15_bits_channels);
		break;
	default:
		indio_dev->channels = ak8974_12_bits_channels;
		indio_dev->num_channels = ARRAY_SIZE(ak8974_12_bits_channels);
		break;
	}
	indio_dev->info = &ak8974_info;
	indio_dev->available_scan_masks = ak8974_scan_masks;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->name = ak8974->name;

	ret = iio_triggered_buffer_setup(indio_dev, NULL,
					 ak8974_handle_trigger,
					 NULL);
	if (ret) {
		dev_err(&i2c->dev, "triggered buffer setup failed\n");
		goto disable_pm;
	}

	/* If we have a valid DRDY IRQ, make use of it */
	if (irq > 0) {
		irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
		if (irq_trig == IRQF_TRIGGER_RISING) {
			dev_info(&i2c->dev, "enable rising edge DRDY IRQ\n");
		} else if (irq_trig == IRQF_TRIGGER_FALLING) {
			ak8974->drdy_active_low = true;
			dev_info(&i2c->dev, "enable falling edge DRDY IRQ\n");
		} else {
			irq_trig = IRQF_TRIGGER_RISING;
		}
		irq_trig |= IRQF_ONESHOT;
		irq_trig |= IRQF_SHARED;

		ret = devm_request_threaded_irq(&i2c->dev,
						irq,
						ak8974_drdy_irq,
						ak8974_drdy_irq_thread,
						irq_trig,
						ak8974->name,
						ak8974);
		if (ret) {
			dev_err(&i2c->dev, "unable to request DRDY IRQ "
				"- proceeding without IRQ\n");
			goto no_irq;
		}
		ak8974->drdy_irq = true;
	}

no_irq:
	ret = iio_device_register(indio_dev);
	if (ret) {
		dev_err(&i2c->dev, "device register failed\n");
		goto cleanup_buffer;
	}

	pm_runtime_set_autosuspend_delay(&i2c->dev,
					 AK8974_AUTOSUSPEND_DELAY);
	pm_runtime_use_autosuspend(&i2c->dev);
	pm_runtime_put(&i2c->dev);

	return 0;

cleanup_buffer:
	iio_triggered_buffer_cleanup(indio_dev);
disable_pm:
	pm_runtime_put_noidle(&i2c->dev);
	pm_runtime_disable(&i2c->dev);
	ak8974_set_power(ak8974, AK8974_PWR_OFF);
	regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs);

	return ret;
}