mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 17:18:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
328
drivers/power/max17058_fuelgauge.c
Executable file
328
drivers/power/max17058_fuelgauge.c
Executable file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* max17058_fuelgauge.c
|
||||
* Samsung MAX17058 Fuel Gauge Driver
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#include <linux/power/sec_fuelgauge.h>
|
||||
|
||||
static int max17058_write_reg(struct i2c_client *client, int reg, u8 *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_smbus_write_i2c_block_data(client, reg, 2, buf);
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max17058_read_reg(struct i2c_client *client, int reg, u8 *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_smbus_read_i2c_block_data(client, reg, 2, buf);
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void max17058_init_regs(struct i2c_client *client)
|
||||
{
|
||||
u8 data[2];
|
||||
|
||||
if (max17058_read_reg(client, MAX17058_REG_STATUS, data) < 0)
|
||||
return ;
|
||||
data[0] |= (1 << 0);
|
||||
max17058_write_reg(client, MAX17058_REG_STATUS, data);
|
||||
|
||||
if (max17058_read_reg(client, MAX17058_REG_STATUS, data) < 0)
|
||||
return ;
|
||||
data[0] &= ~(1 << 0);
|
||||
max17058_write_reg(client, MAX17058_REG_STATUS, data);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
static void max17058_get_version(struct i2c_client *client)
|
||||
{
|
||||
u8 data[2];
|
||||
|
||||
if (max17058_read_reg(client, MAX17058_REG_VERSION, data) < 0)
|
||||
return;
|
||||
|
||||
dev_dbg(&client->dev, "MAX17058 Fuel-Gauge Ver %d%d\n",
|
||||
data[0], data[1]);
|
||||
}
|
||||
|
||||
/* soc should be 0.01% unit */
|
||||
static int max17058_get_soc(struct i2c_client *client)
|
||||
{
|
||||
u8 data[2];
|
||||
int soc;
|
||||
|
||||
if (max17058_read_reg(client, MAX17058_REG_SOC, data) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
soc = ((data[0] * 100) + (data[1] * 100 / 256));
|
||||
|
||||
dev_dbg(&client->dev, "%s: raw capacity (%d)\n", __func__, soc);
|
||||
|
||||
return min(soc, 10000);
|
||||
}
|
||||
|
||||
static int max17058_get_vcell(struct i2c_client *client)
|
||||
{
|
||||
u8 data[2];
|
||||
u32 vcell = 0;
|
||||
|
||||
if (max17058_read_reg(client, MAX17058_REG_VCELL, data) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
vcell = ((data[0] << 8) | data[1]) * 78 / 1000;
|
||||
|
||||
dev_dbg(&client->dev, "%s: vcell (%d)\n", __func__, vcell);
|
||||
|
||||
return vcell;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_init(struct i2c_client *client)
|
||||
{
|
||||
/* initialize fuel gauge registers */
|
||||
max17058_init_regs(client);
|
||||
|
||||
max17058_get_version(client);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_suspend(struct i2c_client *client)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_resume(struct i2c_client *client)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_fuelalert_init(struct i2c_client *client, int soc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_is_fuelalerted(struct i2c_client *client)
|
||||
{
|
||||
u8 data[2];
|
||||
|
||||
max17058_read_reg(client, MAX17058_REG_CONFIG, data);
|
||||
if (data[1] & (1 << 5))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_fuelalert_process(void *irq_data, bool is_fuel_alerted)
|
||||
{
|
||||
struct sec_fuelgauge_info *fuelgauge = irq_data;
|
||||
u8 data[2];
|
||||
|
||||
if (is_fuel_alerted) {
|
||||
dev_info(&fuelgauge->client->dev,
|
||||
"%s: Fuel-alert Alerted!! (%02x%02x)\n",
|
||||
__func__, data[1], data[0]);
|
||||
} else {
|
||||
dev_info(&fuelgauge->client->dev,
|
||||
"%s: Fuel-alert Released!! (%02x%02x)\n",
|
||||
__func__, data[1], data[0]);
|
||||
}
|
||||
|
||||
max17058_read_reg(fuelgauge->client, MAX17058_REG_VCELL, data);
|
||||
dev_dbg(&fuelgauge->client->dev,
|
||||
"%s: MAX17058_REG_VCELL(%02x%02x)\n",
|
||||
__func__, data[1], data[0]);
|
||||
|
||||
max17058_read_reg(fuelgauge->client, MAX17058_REG_SOC, data);
|
||||
dev_dbg(&fuelgauge->client->dev,
|
||||
"%s: MAX17058_REG_SOC(%02x%02x)\n",
|
||||
__func__, data[1], data[0]);
|
||||
|
||||
max17058_read_reg(fuelgauge->client, MAX17058_REG_CONFIG, data);
|
||||
dev_dbg(&fuelgauge->client->dev,
|
||||
"%s: MAX17058_REG_CONFIG(%02x%02x)\n",
|
||||
__func__, data[1], data[0]);
|
||||
|
||||
dev_dbg(&fuelgauge->client->dev,
|
||||
"%s: FUEL GAUGE IRQ (%d)\n",
|
||||
__func__,
|
||||
gpio_get_value(fuelgauge->pdata->fg_irq));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_full_charged(struct i2c_client *client)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_reset(struct i2c_client *client)
|
||||
{
|
||||
u8 data[2];
|
||||
|
||||
if (max17058_read_reg(client, MAX17058_REG_STATUS, data) < 0)
|
||||
return false;
|
||||
data[0] |= (1 << 0);
|
||||
max17058_write_reg(client, MAX17058_REG_STATUS, data);
|
||||
|
||||
if (max17058_read_reg(client, MAX17058_REG_STATUS, data) < 0)
|
||||
return false;
|
||||
data[0] &= ~(1 << 0);
|
||||
max17058_write_reg(client, MAX17058_REG_STATUS, data);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool sec_hal_fg_get_property(struct i2c_client *client,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
switch (psp) {
|
||||
/* Cell voltage (VCELL, mV) */
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
val->intval = max17058_get_vcell(client);
|
||||
break;
|
||||
/* Additional Voltage Information (mV) */
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
|
||||
switch (val->intval) {
|
||||
case SEC_BATTERY_VOLTAGE_AVERAGE:
|
||||
val->intval = 0;
|
||||
break;
|
||||
case SEC_BATTERY_VOLTAGE_OCV:
|
||||
val->intval = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/* Current (mA) */
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
val->intval = 0;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_ENERGY_NOW:
|
||||
val->intval = 0;
|
||||
break;
|
||||
/* Average Current (mA) */
|
||||
case POWER_SUPPLY_PROP_CURRENT_AVG:
|
||||
val->intval = 0;
|
||||
break;
|
||||
/* SOC (%) */
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
if (val->intval == SEC_FUELGAUGE_CAPACITY_TYPE_RAW)
|
||||
val->intval = max17058_get_soc(client);
|
||||
else
|
||||
val->intval = max17058_get_soc(client) / 10;
|
||||
break;
|
||||
/* Battery Temperature */
|
||||
case POWER_SUPPLY_PROP_TEMP:
|
||||
/* Target Temperature */
|
||||
case POWER_SUPPLY_PROP_TEMP_AMBIENT:
|
||||
val->intval = 0;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sec_hal_fg_set_property(struct i2c_client *client,
|
||||
enum power_supply_property psp,
|
||||
const union power_supply_propval *val)
|
||||
{
|
||||
switch (psp) {
|
||||
/* Battery Temperature */
|
||||
case POWER_SUPPLY_PROP_TEMP:
|
||||
/* Target Temperature */
|
||||
case POWER_SUPPLY_PROP_TEMP_AMBIENT:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t sec_hal_fg_show_attrs(struct device *dev,
|
||||
const ptrdiff_t offset, char *buf)
|
||||
{
|
||||
struct power_supply *psy = dev_get_drvdata(dev);
|
||||
struct sec_fuelgauge_info *fg =
|
||||
container_of(psy, struct sec_fuelgauge_info, psy_fg);
|
||||
int i = 0;
|
||||
|
||||
switch (offset) {
|
||||
/* case FG_REG: */
|
||||
/* break; */
|
||||
case FG_DATA:
|
||||
i += scnprintf(buf + i, PAGE_SIZE - i, "%02x%02x\n",
|
||||
fg->reg_data[1], fg->reg_data[0]);
|
||||
break;
|
||||
default:
|
||||
i = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
ssize_t sec_hal_fg_store_attrs(struct device *dev,
|
||||
const ptrdiff_t offset,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct power_supply *psy = dev_get_drvdata(dev);
|
||||
struct sec_fuelgauge_info *fg =
|
||||
container_of(psy, struct sec_fuelgauge_info, psy_fg);
|
||||
int ret = 0;
|
||||
int x = 0;
|
||||
u8 data[2];
|
||||
|
||||
switch (offset) {
|
||||
case FG_REG:
|
||||
if (sscanf(buf, "%x\n", &x) == 1) {
|
||||
fg->reg_addr = x;
|
||||
max17058_read_reg(fg->client,
|
||||
fg->reg_addr, fg->reg_data);
|
||||
dev_dbg(&fg->client->dev,
|
||||
"%s: (read) addr = 0x%x, data = 0x%02x%02x\n",
|
||||
__func__, fg->reg_addr,
|
||||
fg->reg_data[1], fg->reg_data[0]);
|
||||
ret = count;
|
||||
}
|
||||
break;
|
||||
case FG_DATA:
|
||||
if (sscanf(buf, "%x\n", &x) == 1) {
|
||||
data[0] = (x & 0xFF00) >> 8;
|
||||
data[1] = (x & 0x00FF);
|
||||
dev_dbg(&fg->client->dev,
|
||||
"%s: (write) addr = 0x%x, data = 0x%02x%02x\n",
|
||||
__func__, fg->reg_addr, data[1], data[0]);
|
||||
max17058_write_reg(fg->client,
|
||||
fg->reg_addr, data);
|
||||
ret = count;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue