Lines Matching +full:6 +full:- +full:axis
6 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
36 * 16-bit registers are little-endian. LSB is at the address defined below
62 #define AK8974_INT_THRES 0x26 /* Absolute any axis value threshold */
65 /* AK8974-specific offsets */
69 /* AMI305-specific offsets */
78 /* AMI306-specific control register */
83 /* fine axis sensitivity */
88 /* axis sensitivity */
93 /* axis cross-interference */
107 #define AK8974_INT_X_HIGH BIT(7) /* Axis over +threshold */
108 #define AK8974_INT_Y_HIGH BIT(6)
110 #define AK8974_INT_X_LOW BIT(4) /* Axis below -threshold */
113 #define AK8974_INT_RANGE BIT(1) /* Range overflow (any axis) */
115 #define AK8974_STATUS_DRDY BIT(6) /* Data ready */
130 #define AK8974_CTRL3_FORCE BIT(6) /* Start forced measurement */
134 #define AK8974_INT_CTRL_XEN BIT(7) /* Enable interrupt for this axis */
135 #define AK8974_INT_CTRL_YEN BIT(6)
137 #define AK8974_INT_CTRL_XYZEN (BIT(7)|BIT(6)|BIT(5))
164 * struct ak8974 - state container for the AK8974 driver
166 * @orientation: mounting matrix, flipped axis etc
202 ret = regmap_bulk_read(ak8974->map, reg, &bulk, 2); in ak8974_get_u16_val()
214 return regmap_bulk_write(ak8974->map, reg, &bulk, 2); in ak8974_set_u16_val()
224 ret = regmap_write(ak8974->map, AK8974_CTRL1, val); in ak8974_set_power()
242 ret = regmap_write(ak8974->map, AK8974_CTRL2, AK8974_CTRL2_RESDEF); in ak8974_reset()
245 ret = regmap_write(ak8974->map, AK8974_CTRL3, AK8974_CTRL3_RESDEF); in ak8974_reset()
248 ret = regmap_write(ak8974->map, AK8974_INT_CTRL, in ak8974_reset()
261 ret = regmap_write(ak8974->map, AK8974_CTRL2, AK8974_CTRL2_DRDY_EN | in ak8974_configure()
265 ret = regmap_write(ak8974->map, AK8974_CTRL3, 0); in ak8974_configure()
268 if (ak8974->variant == AK8974_WHOAMI_VALUE_AMI306) { in ak8974_configure()
269 /* magic from datasheet: set high-speed measurement mode */ in ak8974_configure()
274 ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL); in ak8974_configure()
278 return regmap_write(ak8974->map, AK8974_PRESET, 0); in ak8974_configure()
289 ret = regmap_read(ak8974->map, AK8974_INT_CLEAR, &clear); in ak8974_trigmeas()
294 if (ak8974->drdy_irq) { in ak8974_trigmeas()
300 if (!ak8974->drdy_active_low) in ak8974_trigmeas()
303 init_completion(&ak8974->drdy_complete); in ak8974_trigmeas()
304 ret = regmap_update_bits(ak8974->map, AK8974_CTRL2, in ak8974_trigmeas()
311 return regmap_update_bits(ak8974->map, in ak8974_trigmeas()
323 if (ak8974->drdy_irq) { in ak8974_await_drdy()
324 ret = wait_for_completion_timeout(&ak8974->drdy_complete, in ak8974_await_drdy()
327 dev_err(&ak8974->i2c->dev, in ak8974_await_drdy()
329 return -ETIMEDOUT; in ak8974_await_drdy()
334 /* Default delay-based poll loop */ in ak8974_await_drdy()
337 ret = regmap_read(ak8974->map, AK8974_STATUS, &val); in ak8974_await_drdy()
342 } while (--timeout); in ak8974_await_drdy()
344 dev_err(&ak8974->i2c->dev, "timeout waiting for DRDY\n"); in ak8974_await_drdy()
345 return -ETIMEDOUT; in ak8974_await_drdy()
356 ret = regmap_read(ak8974->map, AK8974_INT_SRC, &src); in ak8974_getresult()
362 dev_err(&ak8974->i2c->dev, in ak8974_getresult()
364 return -ERANGE; in ak8974_getresult()
367 ret = regmap_bulk_read(ak8974->map, AK8974_DATA_X, result, 6); in ak8974_getresult()
378 if (!ak8974->drdy_irq) in ak8974_drdy_irq()
392 ret = regmap_read(ak8974->map, AK8974_STATUS, &val); in ak8974_drdy_irq_thread()
394 dev_err(&ak8974->i2c->dev, "error reading DRDY status\n"); in ak8974_drdy_irq_thread()
399 complete(&ak8974->drdy_complete); in ak8974_drdy_irq_thread()
409 struct device *dev = &ak8974->i2c->dev; in ak8974_selftest()
413 ret = regmap_read(ak8974->map, AK8974_SELFTEST, &val); in ak8974_selftest()
418 return -EIO; in ak8974_selftest()
421 /* Trigger self-test */ in ak8974_selftest()
422 ret = regmap_update_bits(ak8974->map, in ak8974_selftest()
433 ret = regmap_read(ak8974->map, AK8974_SELFTEST, &val); in ak8974_selftest()
438 return -EIO; in ak8974_selftest()
441 ret = regmap_read(ak8974->map, AK8974_SELFTEST, &val); in ak8974_selftest()
446 return -EIO; in ak8974_selftest()
448 dev_dbg(dev, "passed self-test\n"); in ak8974_selftest()
456 int ret = regmap_bulk_read(ak8974->map, reg, tab, tab_size); in ak8974_read_calib_data()
459 dev_warn(&ak8974->i2c->dev, in ak8974_read_calib_data()
461 reg, reg + tab_size - 1, ret); in ak8974_read_calib_data()
475 ret = regmap_read(ak8974->map, AK8974_WHOAMI, &whoami); in ak8974_detect()
484 /* fall-through */ in ak8974_detect()
486 ret = regmap_read(ak8974->map, AMI305_VER, &fw); in ak8974_detect()
489 fw &= 0x7f; /* only bits 0 thru 6 valid */ in ak8974_detect()
494 dev_info(&ak8974->i2c->dev, in ak8974_detect()
500 dev_info(&ak8974->i2c->dev, "detected AK8974\n"); in ak8974_detect()
503 dev_err(&ak8974->i2c->dev, "unsupported device (%02x) ", in ak8974_detect()
505 return -ENODEV; in ak8974_detect()
508 ak8974->name = name; in ak8974_detect()
509 ak8974->variant = whoami; in ak8974_detect()
521 static const char axis[3] = "XYZ"; in ak8974_detect() local
522 static const char pgaxis[6] = "ZYZXYX"; in ak8974_detect()
526 unsigned pgain1 = le16_to_cpu(fab_data1[i + 6]); in ak8974_detect()
531 dev_info(&ak8974->i2c->dev, in ak8974_detect()
532 "factory calibration for axis %c: offz=%u sens=%u fine=%u pga%c=%u pga%c=%u\n", in ak8974_detect()
533 axis[i], offz, sens, fine, pgaxis[i * 2], in ak8974_detect()
548 int ret = -EINVAL; in ak8974_read_raw()
550 pm_runtime_get_sync(&ak8974->i2c->dev); in ak8974_read_raw()
551 mutex_lock(&ak8974->lock); in ak8974_read_raw()
555 if (chan->address > 2) { in ak8974_read_raw()
556 dev_err(&ak8974->i2c->dev, "faulty channel address\n"); in ak8974_read_raw()
557 ret = -EIO; in ak8974_read_raw()
571 *val = (s16)le16_to_cpu(hw_values[chan->address]); in ak8974_read_raw()
577 mutex_unlock(&ak8974->lock); in ak8974_read_raw()
578 pm_runtime_mark_last_busy(&ak8974->i2c->dev); in ak8974_read_raw()
579 pm_runtime_put_autosuspend(&ak8974->i2c->dev); in ak8974_read_raw()
589 pm_runtime_get_sync(&ak8974->i2c->dev); in ak8974_fill_buffer()
590 mutex_lock(&ak8974->lock); in ak8974_fill_buffer()
594 dev_err(&ak8974->i2c->dev, "error triggering measure\n"); in ak8974_fill_buffer()
597 ret = ak8974_getresult(ak8974, ak8974->scan.channels); in ak8974_fill_buffer()
599 dev_err(&ak8974->i2c->dev, "error getting measures\n"); in ak8974_fill_buffer()
603 iio_push_to_buffers_with_timestamp(indio_dev, &ak8974->scan, in ak8974_fill_buffer()
607 mutex_unlock(&ak8974->lock); in ak8974_fill_buffer()
608 pm_runtime_mark_last_busy(&ak8974->i2c->dev); in ak8974_fill_buffer()
609 pm_runtime_put_autosuspend(&ak8974->i2c->dev); in ak8974_fill_buffer()
615 struct iio_dev *indio_dev = pf->indio_dev; in ak8974_handle_trigger()
618 iio_trigger_notify_done(indio_dev->trig); in ak8974_handle_trigger()
629 return &ak8974->orientation; in ak8974_get_mount_matrix()
637 #define AK8974_AXIS_CHANNEL(axis, index) \ argument
641 .channel2 = IIO_MOD_##axis, \
689 if (ak8974->variant == AK8974_WHOAMI_VALUE_AK8974) in ak8974_writeable_reg()
698 return ak8974->variant == AK8974_WHOAMI_VALUE_AMI305 || in ak8974_writeable_reg()
699 ak8974->variant == AK8974_WHOAMI_VALUE_AMI306; in ak8974_writeable_reg()
702 return ak8974->variant == AK8974_WHOAMI_VALUE_AMI306; in ak8974_writeable_reg()
727 int irq = i2c->irq; in ak8974_probe()
731 indio_dev = devm_iio_device_alloc(&i2c->dev, sizeof(*ak8974)); in ak8974_probe()
733 return -ENOMEM; in ak8974_probe()
737 ak8974->i2c = i2c; in ak8974_probe()
738 mutex_init(&ak8974->lock); in ak8974_probe()
740 ret = of_iio_read_mount_matrix(&i2c->dev, in ak8974_probe()
741 "mount-matrix", in ak8974_probe()
742 &ak8974->orientation); in ak8974_probe()
746 ak8974->regs[0].supply = ak8974_reg_avdd; in ak8974_probe()
747 ak8974->regs[1].supply = ak8974_reg_dvdd; in ak8974_probe()
749 ret = devm_regulator_bulk_get(&i2c->dev, in ak8974_probe()
750 ARRAY_SIZE(ak8974->regs), in ak8974_probe()
751 ak8974->regs); in ak8974_probe()
753 dev_err(&i2c->dev, "cannot get regulators\n"); in ak8974_probe()
757 ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs); in ak8974_probe()
759 dev_err(&i2c->dev, "cannot enable regulators\n"); in ak8974_probe()
764 pm_runtime_get_noresume(&i2c->dev); in ak8974_probe()
765 pm_runtime_set_active(&i2c->dev); in ak8974_probe()
766 pm_runtime_enable(&i2c->dev); in ak8974_probe()
768 ak8974->map = devm_regmap_init_i2c(i2c, &ak8974_regmap_config); in ak8974_probe()
769 if (IS_ERR(ak8974->map)) { in ak8974_probe()
770 dev_err(&i2c->dev, "failed to allocate register map\n"); in ak8974_probe()
771 pm_runtime_put_noidle(&i2c->dev); in ak8974_probe()
772 pm_runtime_disable(&i2c->dev); in ak8974_probe()
773 return PTR_ERR(ak8974->map); in ak8974_probe()
778 dev_err(&i2c->dev, "could not power on\n"); in ak8974_probe()
784 dev_err(&i2c->dev, "neither AK8974 nor AMI30x found\n"); in ak8974_probe()
790 dev_err(&i2c->dev, "selftest failed (continuing anyway)\n"); in ak8974_probe()
794 dev_err(&i2c->dev, "AK8974 reset failed\n"); in ak8974_probe()
798 indio_dev->dev.parent = &i2c->dev; in ak8974_probe()
799 indio_dev->channels = ak8974_channels; in ak8974_probe()
800 indio_dev->num_channels = ARRAY_SIZE(ak8974_channels); in ak8974_probe()
801 indio_dev->info = &ak8974_info; in ak8974_probe()
802 indio_dev->available_scan_masks = ak8974_scan_masks; in ak8974_probe()
803 indio_dev->modes = INDIO_DIRECT_MODE; in ak8974_probe()
804 indio_dev->name = ak8974->name; in ak8974_probe()
810 dev_err(&i2c->dev, "triggered buffer setup failed\n"); in ak8974_probe()
818 dev_info(&i2c->dev, "enable rising edge DRDY IRQ\n"); in ak8974_probe()
820 ak8974->drdy_active_low = true; in ak8974_probe()
821 dev_info(&i2c->dev, "enable falling edge DRDY IRQ\n"); in ak8974_probe()
828 ret = devm_request_threaded_irq(&i2c->dev, in ak8974_probe()
833 ak8974->name, in ak8974_probe()
836 dev_err(&i2c->dev, "unable to request DRDY IRQ " in ak8974_probe()
837 "- proceeding without IRQ\n"); in ak8974_probe()
840 ak8974->drdy_irq = true; in ak8974_probe()
846 dev_err(&i2c->dev, "device register failed\n"); in ak8974_probe()
850 pm_runtime_set_autosuspend_delay(&i2c->dev, in ak8974_probe()
852 pm_runtime_use_autosuspend(&i2c->dev); in ak8974_probe()
853 pm_runtime_put(&i2c->dev); in ak8974_probe()
860 pm_runtime_put_noidle(&i2c->dev); in ak8974_probe()
861 pm_runtime_disable(&i2c->dev); in ak8974_probe()
863 regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs); in ak8974_probe()
875 pm_runtime_get_sync(&i2c->dev); in ak8974_remove()
876 pm_runtime_put_noidle(&i2c->dev); in ak8974_remove()
877 pm_runtime_disable(&i2c->dev); in ak8974_remove()
879 regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs); in ak8974_remove()
890 regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs); in ak8974_runtime_suspend()
901 ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs); in ak8974_runtime_resume()
918 regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs); in ak8974_runtime_resume()
939 { .compatible = "asahi-kasei,ak8974", },
956 MODULE_DESCRIPTION("AK8974 and AMI30x 3-axis magnetometer driver");