Esempio n. 1
0
static int smb347_get_property(struct power_supply *ps,
			enum power_supply_property psp,
			union power_supply_propval *val)
{
	unsigned char value = 0xff;
	int err = 0;

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		err = summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_C, &value);
		if (err < 0)
			val->intval = err;
		else
			val->intval = value & 0x1;
		break;
	case POWER_SUPPLY_PROP_STATUS:
		err = summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_C, &value);
		if (err < 0)
			val->intval = err;
		else
			val->intval =  value & 0x6;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
Esempio n. 2
0
static void summit_smb347_irq_worker(struct work_struct *unused)
{
	unsigned char value = 0xFF;
	int ret = summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_D, &value);
	printk(KERN_INFO "Status register D: 0x%x\n", value);
	
	ret = summit_smb347_i2c_read(SUMMIT_SMB347_INTSTAT_REG_F, &value);
	printk(KERN_INFO "Interrupt Status register F: 0x%x\n", value);

	ret = summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_C, &value);
	printk(KERN_INFO "Status register C: 0x%x\n", value);

	ret = summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_B, &value);
	printk(KERN_INFO "Status register B: 0x%x\n", value);

	enable_irq(summit_smb347_i2c_client->irq);

	return;
}
static int summit_smb347_usb_valid(void)
{
	unsigned char value = 0xff;

	summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_E, &value);

	if (summit_smb347_charger_connected() && (value & 0x80))
		return 1;
	else
		return 0;
}
/* Check to see if charger is connected or not */
static int summit_smb347_charger_connected(void)
{
	unsigned char value = 0xff;

	summit_smb347_i2c_read(SUMMIT_SMB347_INTERRUPT_STAT, &value);

	if (value & 0x4)
		return 1;
	else
		return 0;
}
Esempio n. 5
0
static int summit_smb347_read_id(int *id)
{
	int error = 0;
	unsigned char value = 0xFF;

	error = summit_smb347_i2c_read(SUMMIT_SMB347_ID, &value);

	if (!error) {
		*id = value;
	}

	return error;
}
Esempio n. 6
0
static ssize_t smb347_register_show(struct sys_device *dev, struct sysdev_attribute *attr, char *buf)
{
	unsigned char value = 0xff;
	char *curr = buf;

	summit_smb347_i2c_read(smb347_reg_number, &value);

	curr += sprintf(curr, "SMB347 Register %d\n", smb347_reg_number);
	curr += sprintf(curr, "\n");
	curr += sprintf(curr, " Value: 0x%x\n", value);
	curr += sprintf(curr, "\n");

	return curr - buf;
};
/* Enable/disable charging */
static void summit_smb347_enable_charging(int enable)
{
	unsigned char value = 0xff;

	summit_smb347_i2c_read(SUMMIT_SMB347_COMMAND_REG_A, &value);

	if (!enable) {
		value &= ~(0x2);
	}
	else {
		value |= 0x2;
	}

	summit_smb347_i2c_write(SUMMIT_SMB347_COMMAND_REG_A, value);
	atomic_set(&summit_smb347_charger_state, enable);
}
/* AC property */
static int smb347_get_ac_property(struct power_supply *ps,
			enum power_supply_property psp,
			union power_supply_propval *val)
{
	unsigned char value = 0xff;

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_D, &value);
		val->intval =  value;
		break;
	case POWER_SUPPLY_PROP_STATUS:
		val->intval =  summit_smb347_charger_connected();
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
Esempio n. 9
0
static int summit_smb347_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct summit_smb347_info *info;
	int ret = 0;
#ifdef SUMMIT_SMB347_DEBUG
	int i = 0;
#endif
	int error = 0;
	unsigned char value = 0xff;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		return -ENOMEM;
	}

	client->addr = SUMMIT_SMB347_I2C_ADDRESS;

	i2c_set_clientdata(client, info);
	info->client = client;
	info->charger.name = "summit_smb347";
	info->charger.type = POWER_SUPPLY_TYPE_MAINS;
	info->charger.get_property = smb347_get_property;
	info->charger.properties = smb347_charger_props;
	info->charger.num_properties = ARRAY_SIZE(smb347_charger_props);

	ret = power_supply_register(&client->dev, &info->charger);
	if (ret) {
		dev_err(&client->dev, "failed: power supply register\n");
		i2c_set_clientdata(client, NULL);
		kfree(info);
		return ret;
	}

	summit_smb347_i2c_client = info->client;
	summit_smb347_i2c_client->addr = SUMMIT_SMB347_I2C_ADDRESS;

	if (summit_smb347_read_id(&summit_smb347_id_reg) < 0)
		return -ENODEV;

	printk(KERN_INFO "Summit SMB347 detected, chip_id=0x%x\n", summit_smb347_id_reg);

	ret = request_irq(summit_smb347_i2c_client->irq, summit_smb347_irq,
			IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING, "summit_smb347", NULL);

	if (ret != 0) {
		printk(KERN_ERR "Failed to request IRQ %d: %d\n",
				summit_smb347_i2c_client->irq, ret);
	}

	summit_smb347_init_registers();

#ifdef SUMMIT_SMB347_DEBUG
	for (i = 0; i <= 0xE; i++) {
		ret = summit_smb347_i2c_read(i, &value);
		printk(KERN_INFO "summit_smb347: reg=%d, value=0x%x\n", i, value);
	}

	for (i = 0x30; i <= 0x3F; i++) {
		ret = summit_smb347_i2c_read(i, &value);
		printk(KERN_INFO "summit_smb347: reg=%d, value=0x%x\n", i, value);
	}
#endif

	error = sysdev_class_register(&smb347_reg_sysclass);

	if (!error)
		error = sysdev_register(&device_smb347_reg);

	if (!error)
		error = sysdev_create_file(&device_smb347_reg, &attr_smb347_reg);

	error = sysdev_class_register(&smb347_register_sysclass);
	if (!error)
		error = sysdev_register(&device_smb347_register);
	if (!error)
		error = sysdev_create_file(&device_smb347_register, &attr_smb347_register);

	return 0;
}
static int smb347_get_battery_property(struct power_supply *ps,
			enum power_supply_property psp,
			union power_supply_propval *val)
{
	unsigned char value = 0xff;
	int err = 0;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		err = summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_C, &value);
		if (err < 0)
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		else {
			if (value & 0x6)
				val->intval = POWER_SUPPLY_STATUS_CHARGING;
			else
				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		}
		break;
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		err = summit_smb347_i2c_read(SUMMIT_SMB347_STATUS_REG_C, &value);
		if (err < 0)
			val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
		else {
			if (value & 0x4)
				val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
			if (value & 0x2)
				val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
		}
		break;
	case POWER_SUPPLY_PROP_TEMP:
		val->intval = bq27541_temperature;
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
		val->intval = bq27541_battery_capacity;
		break;
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
		val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;

		if (bq27541_battery_capacity <= 5)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;

		if (bq27541_battery_capacity > 80)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;

		if (bq27541_battery_capacity == 100)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;

		if (bq27541_battery_capacity <= 20)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;

		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = bq27541_voltage;
		break;
	case POWER_SUPPLY_PROP_HEALTH:
		val->intval = POWER_SUPPLY_HEALTH_GOOD;

		if (summit_smb347_temperature_hot)
			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;

		if (summit_smb347_temperature_cold)
			val->intval = POWER_SUPPLY_HEALTH_COLD;

		if (summit_smb347_voltage_hi)
			val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;

		if (summit_smb347_voltage_low)
			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}