From 14a8d7c10062a9348b4ea90f5bca3b0cb6872c1b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pali=20Roh=C3=A1r?= Date: Sat, 8 Sep 2012 13:02:53 +0200 Subject: [PATCH] bq2415x_charger patch: minor changes --- .../debian/patches/bq2415x_charger.patch | 128 ++++++++++++++------ 1 file changed, 93 insertions(+), 35 deletions(-) diff --git a/kernel-power-2.6.28/debian/patches/bq2415x_charger.patch b/kernel-power-2.6.28/debian/patches/bq2415x_charger.patch index ed59611..40217e2 100644 --- a/kernel-power-2.6.28/debian/patches/bq2415x_charger.patch +++ b/kernel-power-2.6.28/debian/patches/bq2415x_charger.patch @@ -1,6 +1,6 @@ --- /dev/null +++ kernel-power/drivers/power/bq2415x_charger.c -@@ -0,0 +1,1579 @@ +@@ -0,0 +1,1637 @@ +/* + bq2415x_charger.c - bq2415x charger driver + Copyright (C) 2011-2012 Pali Rohár @@ -45,7 +45,8 @@ + +#include + -+#define BQ2415X_TIMER_TIMEOUT 10 ++/* timeout for resetting chip timer */ ++#define BQ2415X_TIMER_TIMEOUT 10 + +#define BQ2415X_REG_STATUS 0x00 +#define BQ2415X_REG_CONTROL 0x01 @@ -182,14 +183,16 @@ + int id; +}; + ++/* each registered chip must have unique id */ +static DEFINE_IDR(bq2415x_id); + +static DEFINE_MUTEX(bq2415x_id_mutex); +static DEFINE_MUTEX(bq2415x_timer_mutex); +static DEFINE_MUTEX(bq2415x_i2c_mutex); + -+/* i2c read functions */ ++/**** i2c read functions ****/ + ++/* read value from register */ +static int bq2415x_i2c_read(struct bq2415x_device *bq, u8 reg) +{ + struct i2c_client *client = to_i2c_client(bq->dev); @@ -219,6 +222,7 @@ + return val; +} + ++/* read value from register, apply mask and right shift it */ +static int bq2415x_i2c_read_mask(struct bq2415x_device *bq, u8 reg, + u8 mask, u8 shift) +{ @@ -234,6 +238,7 @@ + return (ret & mask) >> shift; +} + ++/* read value from register and return one specified bit */ +static int bq2415x_i2c_read_bit(struct bq2415x_device *bq, u8 reg, u8 bit) +{ + if (bit > 8) @@ -242,8 +247,9 @@ + return bq2415x_i2c_read_mask(bq, reg, BIT(bit), bit); +} + -+/* i2c write functions */ ++/**** i2c write functions ****/ + ++/* write value to register */ +static int bq2415x_i2c_write(struct bq2415x_device *bq, u8 reg, u8 val) +{ + struct i2c_client *client = to_i2c_client(bq->dev); @@ -272,6 +278,7 @@ + return 0; +} + ++/* read value from register, change it with mask left shifted and write back */ +static int bq2415x_i2c_write_mask(struct bq2415x_device *bq, u8 reg, u8 val, + u8 mask, u8 shift) +{ @@ -290,6 +297,7 @@ + return bq2415x_i2c_write(bq, reg, ret); +} + ++/* change only one bit in register */ +static int bq2415x_i2c_write_bit(struct bq2415x_device *bq, u8 reg, + bool val, u8 bit) +{ @@ -299,8 +307,9 @@ + return bq2415x_i2c_write_mask(bq, reg, val, BIT(bit), bit); +} + -+/* global exec command function */ ++/**** global functions ****/ + ++/* exec command function */ +static int bq2415x_exec_command(struct bq2415x_device *bq, + enum bq2415x_command command) +{ @@ -406,8 +415,7 @@ + } +} + -+/* global detect chip */ -+ ++/* detect chip type */ +static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq) +{ + struct i2c_client *client = to_i2c_client(bq->dev); @@ -459,6 +467,7 @@ + return BQUNKNOWN; +} + ++/* detect chip revision */ +static int bq2415x_detect_revision(struct bq2415x_device *bq) +{ + int ret = bq2415x_exec_command(bq, BQ2415X_REVISION); @@ -502,6 +511,7 @@ + return -1; +} + ++/* return chip vender code */ +static int bq2415x_get_vender_code(struct bq2415x_device *bq) +{ + int ret = bq2415x_exec_command(bq, BQ2415X_VENDER_CODE); @@ -513,8 +523,7 @@ + ((ret >> 2) & 0x1) * 100; +} + -+/* global other functions */ -+ ++/* reset all chip registers to default state */ +static void bq2415x_reset_chip(struct bq2415x_device *bq) +{ + bq2415x_i2c_write(bq, BQ2415X_REG_CURRENT, BQ2415X_RESET_CURRENT); @@ -523,6 +532,9 @@ + bq2415x_i2c_write(bq, BQ2415X_REG_STATUS, BQ2415X_RESET_STATUS); +} + ++/**** properties functions ****/ ++ ++/* set current limit in mA */ +static int bq2415x_set_current_limit(struct bq2415x_device *bq, int mA) +{ + int val; @@ -538,6 +550,7 @@ + BQ2415X_MASK_LIMIT, BQ2415X_SHIFT_LIMIT); +} + ++/* get current limit in mA */ +static int bq2415x_get_current_limit(struct bq2415x_device *bq) +{ + int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL, @@ -556,6 +569,7 @@ + return -EINVAL; +} + ++/* set weak battery voltage in mV */ +static int bq2415x_set_weak_battery_voltage(struct bq2415x_device *bq, int mV) +{ + /* round to 100mV */ @@ -572,6 +586,7 @@ + BQ2415X_MASK_VLOWV, BQ2415X_SHIFT_VLOWV); +} + ++/* get weak battery voltage in mV */ +static int bq2415x_get_weak_battery_voltage(struct bq2415x_device *bq) +{ + int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL, @@ -582,6 +597,7 @@ + return 100 * (34 + ret); +} + ++/* set battery regulation voltage in mV */ +static int bq2415x_set_battery_regulation_voltage(struct bq2415x_device *bq, + int mV) +{ @@ -596,6 +612,7 @@ + BQ2415X_MASK_VO, BQ2415X_SHIFT_VO); +} + ++/* get battery regulation voltage in mV */ +static int bq2415x_get_battery_regulation_voltage(struct bq2415x_device *bq) +{ + int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_VOLTAGE, @@ -606,6 +623,7 @@ + return 10 * (350 + 2*ret); +} + ++/* set charge current in mA (platform data must provide resistor sense) */ +static int bq2415x_set_charge_current(struct bq2415x_device *bq, int mA) +{ + int val; @@ -624,6 +642,7 @@ + BQ2415X_SHIFT_VI_CHRG); +} + ++/* get charge current in mA (platform data must provide resistor sense) */ +static int bq2415x_get_charge_current(struct bq2415x_device *bq) +{ + int ret; @@ -638,6 +657,7 @@ + return (37400 + 6800*ret) / bq->init_data.resistor_sense; +} + ++/* set termination current in mA (platform data must provide resistor sense) */ +static int bq2415x_set_termination_current(struct bq2415x_device *bq, int mA) +{ + int val; @@ -656,6 +676,7 @@ + BQ2415X_SHIFT_VI_TERM); +} + ++/* get termination current in mA (platform data must provide resistor sense) */ +static int bq2415x_get_termination_current(struct bq2415x_device *bq) +{ + int ret; @@ -670,19 +691,22 @@ + return (3400 + 3400*ret) / bq->init_data.resistor_sense; +} + -+#define bq2415x_set_default_value(bq, value) \ ++/* set default value of property */ ++#define bq2415x_set_default_value(bq, prop) \ + do { \ + int ret = 0; \ -+ if (bq->init_data.value != -1) \ -+ ret = bq2415x_set_##value(bq, bq->init_data.value); \ ++ if (bq->init_data.prop != -1) \ ++ ret = bq2415x_set_##prop(bq, bq->init_data.prop); \ + if (ret < 0) \ + return ret; \ + } while (0) + ++/* set default values of all properties */ +static int bq2415x_set_defaults(struct bq2415x_device *bq) +{ + bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE); + bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE); ++ bq2415x_exec_command(bq, BQ2415X_CHARGE_TERMINATION_DISABLE); + bq2415x_set_default_value(bq, current_limit); + bq2415x_set_default_value(bq, weak_battery_voltage); + bq2415x_set_default_value(bq, battery_regulation_voltage); @@ -695,8 +719,9 @@ + return 0; +} + -+/* charger mode functions */ ++/**** charger mode functions ****/ + ++/* set charger mode */ +static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode) +{ + int ret = 0; @@ -759,6 +784,7 @@ + +} + ++/* hook function called by other driver which set reported mode */ +static void bq2415x_hook_function(enum bq2415x_mode mode, void *data) +{ + struct bq2415x_device *bq = data; @@ -766,20 +792,22 @@ + if (!bq) + return; + ++ /* this should not happen, hook function is called only in automode */ ++ if (bq->automode < 1) ++ return; ++ + dev_dbg(bq->dev, "hook function was called\n"); + + bq->reported_mode = mode; + sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode"); + -+ if (bq->automode < 1) -+ return; -+ + bq2415x_set_mode(bq, bq->reported_mode); + +} + -+/* timer functions */ ++/**** timer functions ****/ + ++/* enable/disable auto resetting chip timer */ +static void bq2415x_set_autotimer(struct bq2415x_device *bq, int state) +{ + mutex_lock(&bq2415x_timer_mutex); @@ -801,6 +829,7 @@ + mutex_unlock(&bq2415x_timer_mutex); +} + ++/* called by bq2415x_timer_work on timer error */ +static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg) +{ + dev_err(bq->dev, "%s\n", msg); @@ -810,6 +839,7 @@ + bq2415x_set_autotimer(bq, 0); +} + ++/* delayed work function for auto resetting chip timer */ +static void bq2415x_timer_work(struct work_struct *work) +{ + struct bq2415x_device *bq = container_of(work, struct bq2415x_device, @@ -821,7 +851,7 @@ + + ret = bq2415x_exec_command(bq, BQ2415X_TIMER_RESET); + if (ret < 0) { -+ bq2415x_timer_error(bq, "Reseting timer failed"); ++ bq2415x_timer_error(bq, "Resetting timer failed"); + return; + } + @@ -839,6 +869,7 @@ + + if (boost) { + switch (error) { ++ /* Non fatal errors, chip is OK */ + case 0: /* No error */ + break; + case 6: /* Timer expired */ @@ -848,9 +879,10 @@ + dev_err(bq->dev, "Battery voltage to low\n"); + break; + ++ /* Fatal errors, disable and reset chip */ + case 1: /* Overvoltage protection (chip fried) */ + bq2415x_timer_error(bq, -+ "Overvolatge protection (chip fried)"); ++ "Overvoltage protection (chip fried)"); + return; + case 2: /* Overload */ + bq2415x_timer_error(bq, "Overload"); @@ -869,6 +901,7 @@ + } + } else { + switch (error) { ++ /* Non fatal errors, chip is OK */ + case 0: /* No error */ + break; + case 2: /* Sleep mode */ @@ -884,9 +917,10 @@ + dev_err(bq->dev, "No battery\n"); + break; + ++ /* Fatal errors, disable and reset chip */ + case 1: /* Overvoltage protection (chip fried) */ + bq2415x_timer_error(bq, -+ "Overvolatge protection (chip fried)"); ++ "Overvoltage protection (chip fried)"); + return; + case 4: /* Battery overvoltage protection */ + bq2415x_timer_error(bq, @@ -902,10 +936,10 @@ + schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ); +} + -+/* power supply */ ++/**** power supply interface code ****/ + +static enum power_supply_property bq2415x_power_supply_props[] = { -+ /* TODO: more power supply properties */ ++ /* TODO: maybe add more power supply properties */ + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_MODEL_NAME, +}; @@ -992,8 +1026,9 @@ + kfree(bq->model); +} + -+/* sysfs files */ ++/**** additional sysfs entries for power supply interface ****/ + ++/* show *_status entries */ +static ssize_t bq2415x_sysfs_show_status(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -1021,6 +1056,11 @@ + return sprintf(buf, "%d\n", ret); +} + ++/* set timer entry: ++ auto - enable auto mode ++ off - disable auto mode ++ (other values) - reset chip timer ++*/ +static ssize_t bq2415x_sysfs_set_timer(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ @@ -1042,6 +1082,7 @@ + return count; +} + ++/* show timer entry (auto or off) */ +static ssize_t bq2415x_sysfs_show_timer(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -1055,6 +1096,13 @@ + return sprintf(buf, "off\n"); +} + ++/* set mode entry: ++ auto - if automode is supported, enable it and set mode to reported ++ none - disable charger and boost mode ++ host - charging mode for host/hub chargers (current limit 500mA) ++ dedicated - charging mode for dedicated chargers (unlimited current limit) ++ boost - disable charger and enable boost mode ++*/ +static ssize_t bq2415x_sysfs_set_mode(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ @@ -1088,9 +1136,10 @@ + } else if (strncmp(buf, "reset", 5) == 0) { + bq2415x_reset_chip(bq); + bq2415x_set_defaults(bq); -+ if (bq->automode > 0) -+ bq->automode = 1; -+ return count; ++ if (bq->automode <= 0) ++ return count; ++ bq->automode = 1; ++ mode = bq->reported_mode; + } else + return -EINVAL; + @@ -1101,6 +1150,7 @@ + return count; +} + ++/* show mode entry (auto, none, host, dedicated or boost) */ +static ssize_t bq2415x_sysfs_show_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -1134,6 +1184,7 @@ + return ret; +} + ++/* show reported_mode entry (none, host, dedicated or boost) */ +static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -1141,6 +1192,9 @@ + struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, + charger); + ++ if (bq->automode < 0) ++ return -EINVAL; ++ + switch (bq->reported_mode) { + case BQ2415X_MODE_NONE: + return sprintf(buf, "none\n"); @@ -1155,6 +1209,7 @@ + return -EINVAL; +} + ++/* directly set raw value to chip register, format: 'register value' */ +static ssize_t bq2415x_sysfs_set_registers(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ @@ -1178,6 +1233,7 @@ + return count; +} + ++/* print value of chip register, format: 'register=value' */ +static ssize_t bq2415x_sysfs_print_reg(struct bq2415x_device *bq, + u8 reg, char *buf) +{ @@ -1188,6 +1244,7 @@ + return sprintf(buf, "%#.2x=%#.2x\n", reg, ret); +} + ++/* show all raw values of chip register, format per line: 'register=value' */ +static ssize_t bq2415x_sysfs_show_registers(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -1204,8 +1261,7 @@ + return ret; +} + -+/* Current & Volatage settings */ -+ ++/* set current and voltage limit entries (in mA or mV) */ +static ssize_t bq2415x_sysfs_set_limit(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ @@ -1237,6 +1293,7 @@ + return count; +} + ++/* show current and voltage limit entries (in mA or mV) */ +static ssize_t bq2415x_sysfs_show_limit(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -1264,6 +1321,7 @@ + return sprintf(buf, "%d\n", ret); +} + ++/* set *_enable entries */ +static ssize_t bq2415x_sysfs_set_enable(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ @@ -1299,6 +1357,7 @@ + return count; +} + ++/* show *_enable entries */ +static ssize_t bq2415x_sysfs_show_enable(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -1401,8 +1460,7 @@ + sysfs_remove_group(&bq->charger.dev->kobj, &bq2415x_sysfs_attr_group); +} + -+/* bq2415x register */ -+ ++/* main bq2415x probe function */ +static int bq2415x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ @@ -1494,7 +1552,7 @@ + INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work); + bq2415x_set_autotimer(bq, 1); + -+ dev_info(bq->dev, "driver registred\n"); ++ dev_info(bq->dev, "driver registered\n"); + return 0; + +error_5: @@ -1513,7 +1571,7 @@ + return ret; +} + -+/* bq2415x unregister */ ++/* main bq2415x remove function */ + +static int bq2415x_remove(struct i2c_client *client) +{ @@ -1531,7 +1589,7 @@ + idr_remove(&bq2415x_id, bq->id); + mutex_unlock(&bq2415x_id_mutex); + -+ dev_info(bq->dev, "driver unregistred\n"); ++ dev_info(bq->dev, "driver unregistered\n"); + + kfree(bq->name); + kfree(bq); @@ -1629,7 +1687,7 @@ + platform_data->set_mode_hook(bq2415x_hook_function, bq2415x_device); + + Board/platform function set_mode_hook return non zero value when hook -+ function was successfull registred. Platform code should call that hook ++ function was successful registered. Platform code should call that hook + function (which get from pointer, with data) every time when charger was + connected/disconnected or require to enable boost mode. bq2415x driver then + will set correct current limit, enable/disable charger or boost mode. @@ -1647,7 +1705,7 @@ + + (hook function and driver private data are NULL) + -+ After thet board/platform code must not call driver hook function! It is ++ After that board/platform code must not call driver hook function! It is + possible that pointer to hook function will not be valid and calling will + cause undefined result. + -- 1.7.9.5