+struct ao_mmc5983_sample ao_mmc5983_current;
+
+static uint8_t ao_mmc5983_configured;
+
+#ifdef MMC5983_I2C
+#include <ao_i2c_bit.h>
+
+static void
+ao_mmc5983_reg_write(uint8_t addr, uint8_t data)
+{
+ uint8_t d[2];
+
+ d[0] = addr;
+ d[1] = data;
+
+ ao_i2c_bit_start(MMC5983_I2C_ADDR);
+ ao_i2c_bit_send(d, 2);
+ ao_i2c_bit_stop();
+}
+
+static uint8_t
+ao_mmc5983_reg_read(uint8_t addr)
+{
+ uint8_t d[1];
+
+ ao_i2c_bit_start(MMC5983_I2C_ADDR);
+ d[0] = addr;
+ ao_i2c_bit_send(d, 1);
+ ao_i2c_bit_restart(MMC5983_I2C_ADDR | 1);
+ ao_i2c_bit_recv(d, 1);
+ ao_i2c_bit_stop();
+ return d[0];
+}
+
+static void
+ao_mmc5983_sample(struct ao_mmc5983_sample *sample)
+{
+ struct ao_mmc5983_raw raw;
+
+ ao_i2c_bit_start(MMC5983_I2C_ADDR);
+ raw.addr = MMC5983_X_OUT_0;
+ ao_i2c_bit_send(&raw.addr, 1);
+ ao_i2c_bit_restart(MMC5983_I2C_ADDR | 1);
+ ao_i2c_bit_recv(&raw.x0, 7);
+ ao_i2c_bit_stop();
+
+ sample->x = raw.x0 << 10 | raw.x1 << 2 | ((raw.xyz2 >> 6) & 3);
+ sample->y = raw.y0 << 10 | raw.y1 << 2 | ((raw.xyz2 >> 4) & 3);
+ sample->z = raw.z0 << 10 | raw.z1 << 2 | ((raw.xyz2 >> 2) & 3);
+}
+
+#else
+#define AO_MMC5983_SPI_SPEED ao_spi_speed(2000000)