/*
 * Copyright (c) 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <zephyr.h>

#include <misc/printk.h>

#include <device.h>
#include <i2c.h>

/**
 * @file Sample app using the TI INA219 through I2C.
 */

#define I2C_SLV_ADDR	0x40

/* The calibration value is based on components on
 * Adafruit's breakout board
 * (https://www.adafruit.com/products/904), where
 * the current sensing resistor is 0.1 ohm.
 * This enables measurements up to 32V, 2A.
 */
#define CAL_VAL		(4096)

/* With default calibration above,
 * Each current LSB is 100 uA == 0.1 mA == 0.0001 A.
 * Each power LSB is 2000 uW == 2 mW = 0.002W.
 */
#define CUR_LSB		100
#define PWR_LSB		2000

int read_reg16(struct device *i2c_dev, uint8_t reg_addr,
	       uint8_t *data)
{
	uint8_t wr_addr;
	struct i2c_msg msgs[2];

	/* Register address */
	wr_addr = reg_addr;

	/* Setup I2C messages */

	/* Send the address to read */
	msgs[0].buf = &wr_addr;
	msgs[0].len = 1;
	msgs[0].flags = I2C_MSG_WRITE;

	/* Read from device. RESTART as neededm and STOP after this. */
	msgs[1].buf = data;
	msgs[1].len = 2;
	msgs[1].flags = I2C_MSG_READ | I2C_MSG_RESTART | I2C_MSG_STOP;

	return i2c_transfer(i2c_dev, &msgs[0], 2, I2C_SLV_ADDR);
}

int write_reg16(struct device *i2c_dev, uint8_t reg_addr,
		uint8_t *data)
{
	uint8_t wr_addr;
	struct i2c_msg msgs[2];

	/* Register address */
	wr_addr = reg_addr;

	/* Setup I2C messages */

	/* Send the address to read */
	msgs[0].buf = &wr_addr;
	msgs[0].len = 1;
	msgs[0].flags = I2C_MSG_WRITE;

	/* Read from device. RESTART as neededm and STOP after this. */
	msgs[1].buf = data;
	msgs[1].len = 2;
	msgs[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

	return i2c_transfer(i2c_dev, &msgs[0], 2, I2C_SLV_ADDR);
}

void main(void)
{
	struct device *i2c_dev;
	uint8_t data[2];
	uint32_t shunt_volt, bus_volt, current, power;

	i2c_dev = device_get_binding("I2C0");
	if (!i2c_dev) {
		printk("I2C: Device not found.\n");
	}

	/* Configurate the chip using default values */
	data[0] = 0x03;
	data[1] = 0x99;
	write_reg16(i2c_dev, 0x00, data);

	/* Write the calibration value */
	data[0] = (CAL_VAL & 0xFF00) >> 8;
	data[1] = CAL_VAL & 0xFF;
	write_reg16(i2c_dev, 0x05, data);

	/* Read bus voltage */
	read_reg16(i2c_dev, 0x02, data);
	bus_volt = (data[0] << 8) | data[1];
	bus_volt >>= 3; /* 3 LSBs are not data */
	bus_volt *= 4; /* each LSB is 4 mV */
	printk("Bus Voltage: %d mV\n", bus_volt);

	/* Read shunt voltage */
	read_reg16(i2c_dev, 0x01, data);
	shunt_volt = (data[0] << 8) | data[1];
	shunt_volt *= 10; /* to uV since each LSB is 0.01 mV */
	printk("Shunt Voltage: %d uV\n", shunt_volt);

	/* Read current */
	read_reg16(i2c_dev, 0x04, data);
	current = (data[0] << 8) | data[1];
	current *= CUR_LSB;
	printk("Current: %d uA\n", current);

	/* Read power  */
	read_reg16(i2c_dev, 0x03, data);
	power = (data[0] << 8) | data[1];
	power *= PWR_LSB;
	printk("Power: %d uW\n", power);
}
