diff options
| author | Yulia Vilensky <vilensky@compulab.co.il> | 2010-04-26 07:05:25 -0400 |
|---|---|---|
| committer | Anton Vorontsov <cbouatmailru@gmail.com> | 2010-04-26 14:03:42 -0400 |
| commit | 9b9ade6b612e562c4a5bd02ef38cc32e10f3f9ba (patch) | |
| tree | 97b8e0130934a6bb08b1f4c083ed15a7db62abf1 | |
| parent | 8ef1bb539203629f77a61976e4f25415e1083bff (diff) | |
ds2782_battery: Add support for ds2786 battery gas gauge
Signed-off-by: Yulia Vilensky <vilensky@compulab.co.il>
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
| -rw-r--r-- | drivers/power/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/power/ds2782_battery.c | 184 | ||||
| -rw-r--r-- | include/linux/ds2782_battery.h | 8 |
3 files changed, 146 insertions, 50 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 22f2fa912127..c59bcb7c6eb0 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
| @@ -65,10 +65,10 @@ config BATTERY_DS2760 | |||
| 65 | Say Y here to enable support for batteries with ds2760 chip. | 65 | Say Y here to enable support for batteries with ds2760 chip. |
| 66 | 66 | ||
| 67 | config BATTERY_DS2782 | 67 | config BATTERY_DS2782 |
| 68 | tristate "DS2782 standalone gas-gauge" | 68 | tristate "DS2782/DS2786 standalone gas-gauge" |
| 69 | depends on I2C | 69 | depends on I2C |
| 70 | help | 70 | help |
| 71 | Say Y here to enable support for the DS2782 standalone battery | 71 | Say Y here to enable support for the DS2782/DS2786 standalone battery |
| 72 | gas-gauge. | 72 | gas-gauge. |
| 73 | 73 | ||
| 74 | config BATTERY_PMU | 74 | config BATTERY_PMU |
diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index ba1bd1a545be..c665e8007235 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | * Author: Ryan Mallon <ryan@bluewatersys.com> | 6 | * Author: Ryan Mallon <ryan@bluewatersys.com> |
| 7 | * | 7 | * |
| 8 | * DS2786 added by Yulia Vilensky <vilensky@compulab.co.il> | ||
| 9 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
| 10 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| @@ -20,12 +22,13 @@ | |||
| 20 | #include <linux/idr.h> | 22 | #include <linux/idr.h> |
| 21 | #include <linux/power_supply.h> | 23 | #include <linux/power_supply.h> |
| 22 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <linux/ds2782_battery.h> | ||
| 23 | 26 | ||
| 24 | #define DS2782_REG_RARC 0x06 /* Remaining active relative capacity */ | 27 | #define DS2782_REG_RARC 0x06 /* Remaining active relative capacity */ |
| 25 | 28 | ||
| 26 | #define DS2782_REG_VOLT_MSB 0x0c | 29 | #define DS278x_REG_VOLT_MSB 0x0c |
| 27 | #define DS2782_REG_TEMP_MSB 0x0a | 30 | #define DS278x_REG_TEMP_MSB 0x0a |
| 28 | #define DS2782_REG_CURRENT_MSB 0x0e | 31 | #define DS278x_REG_CURRENT_MSB 0x0e |
| 29 | 32 | ||
| 30 | /* EEPROM Block */ | 33 | /* EEPROM Block */ |
| 31 | #define DS2782_REG_RSNSP 0x69 /* Sense resistor value */ | 34 | #define DS2782_REG_RSNSP 0x69 /* Sense resistor value */ |
| @@ -33,18 +36,33 @@ | |||
| 33 | /* Current unit measurement in uA for a 1 milli-ohm sense resistor */ | 36 | /* Current unit measurement in uA for a 1 milli-ohm sense resistor */ |
| 34 | #define DS2782_CURRENT_UNITS 1563 | 37 | #define DS2782_CURRENT_UNITS 1563 |
| 35 | 38 | ||
| 36 | #define to_ds2782_info(x) container_of(x, struct ds2782_info, battery) | 39 | #define DS2786_REG_RARC 0x02 /* Remaining active relative capacity */ |
| 40 | |||
| 41 | #define DS2786_CURRENT_UNITS 25 | ||
| 42 | |||
| 43 | struct ds278x_info; | ||
| 44 | |||
| 45 | struct ds278x_battery_ops { | ||
| 46 | int (*get_current)(struct ds278x_info *info, int *current_uA); | ||
| 47 | int (*get_voltage)(struct ds278x_info *info, int *voltage_uA); | ||
| 48 | int (*get_capacity)(struct ds278x_info *info, int *capacity_uA); | ||
| 49 | |||
| 50 | }; | ||
| 51 | |||
| 52 | #define to_ds278x_info(x) container_of(x, struct ds278x_info, battery) | ||
| 37 | 53 | ||
| 38 | struct ds2782_info { | 54 | struct ds278x_info { |
| 39 | struct i2c_client *client; | 55 | struct i2c_client *client; |
| 40 | struct power_supply battery; | 56 | struct power_supply battery; |
| 57 | struct ds278x_battery_ops *ops; | ||
| 41 | int id; | 58 | int id; |
| 59 | int rsns; | ||
| 42 | }; | 60 | }; |
| 43 | 61 | ||
| 44 | static DEFINE_IDR(battery_id); | 62 | static DEFINE_IDR(battery_id); |
| 45 | static DEFINE_MUTEX(battery_lock); | 63 | static DEFINE_MUTEX(battery_lock); |
| 46 | 64 | ||
| 47 | static inline int ds2782_read_reg(struct ds2782_info *info, int reg, u8 *val) | 65 | static inline int ds278x_read_reg(struct ds278x_info *info, int reg, u8 *val) |
| 48 | { | 66 | { |
| 49 | int ret; | 67 | int ret; |
| 50 | 68 | ||
| @@ -58,7 +76,7 @@ static inline int ds2782_read_reg(struct ds2782_info *info, int reg, u8 *val) | |||
| 58 | return 0; | 76 | return 0; |
| 59 | } | 77 | } |
| 60 | 78 | ||
| 61 | static inline int ds2782_read_reg16(struct ds2782_info *info, int reg_msb, | 79 | static inline int ds278x_read_reg16(struct ds278x_info *info, int reg_msb, |
| 62 | s16 *val) | 80 | s16 *val) |
| 63 | { | 81 | { |
| 64 | int ret; | 82 | int ret; |
| @@ -73,7 +91,7 @@ static inline int ds2782_read_reg16(struct ds2782_info *info, int reg_msb, | |||
| 73 | return 0; | 91 | return 0; |
| 74 | } | 92 | } |
| 75 | 93 | ||
| 76 | static int ds2782_get_temp(struct ds2782_info *info, int *temp) | 94 | static int ds278x_get_temp(struct ds278x_info *info, int *temp) |
| 77 | { | 95 | { |
| 78 | s16 raw; | 96 | s16 raw; |
| 79 | int err; | 97 | int err; |
| @@ -84,14 +102,14 @@ static int ds2782_get_temp(struct ds2782_info *info, int *temp) | |||
| 84 | * celsius. The temperature value is stored as a 10 bit number, plus | 102 | * celsius. The temperature value is stored as a 10 bit number, plus |
| 85 | * sign in the upper bits of a 16 bit register. | 103 | * sign in the upper bits of a 16 bit register. |
| 86 | */ | 104 | */ |
| 87 | err = ds2782_read_reg16(info, DS2782_REG_TEMP_MSB, &raw); | 105 | err = ds278x_read_reg16(info, DS278x_REG_TEMP_MSB, &raw); |
| 88 | if (err) | 106 | if (err) |
| 89 | return err; | 107 | return err; |
| 90 | *temp = ((raw / 32) * 125) / 100; | 108 | *temp = ((raw / 32) * 125) / 100; |
| 91 | return 0; | 109 | return 0; |
| 92 | } | 110 | } |
| 93 | 111 | ||
| 94 | static int ds2782_get_current(struct ds2782_info *info, int *current_uA) | 112 | static int ds2782_get_current(struct ds278x_info *info, int *current_uA) |
| 95 | { | 113 | { |
| 96 | int sense_res; | 114 | int sense_res; |
| 97 | int err; | 115 | int err; |
| @@ -102,7 +120,7 @@ static int ds2782_get_current(struct ds2782_info *info, int *current_uA) | |||
| 102 | * The units of measurement for current are dependent on the value of | 120 | * The units of measurement for current are dependent on the value of |
| 103 | * the sense resistor. | 121 | * the sense resistor. |
| 104 | */ | 122 | */ |
| 105 | err = ds2782_read_reg(info, DS2782_REG_RSNSP, &sense_res_raw); | 123 | err = ds278x_read_reg(info, DS2782_REG_RSNSP, &sense_res_raw); |
| 106 | if (err) | 124 | if (err) |
| 107 | return err; | 125 | return err; |
| 108 | if (sense_res_raw == 0) { | 126 | if (sense_res_raw == 0) { |
| @@ -113,14 +131,14 @@ static int ds2782_get_current(struct ds2782_info *info, int *current_uA) | |||
| 113 | 131 | ||
| 114 | dev_dbg(&info->client->dev, "sense resistor = %d milli-ohms\n", | 132 | dev_dbg(&info->client->dev, "sense resistor = %d milli-ohms\n", |
| 115 | sense_res); | 133 | sense_res); |
| 116 | err = ds2782_read_reg16(info, DS2782_REG_CURRENT_MSB, &raw); | 134 | err = ds278x_read_reg16(info, DS278x_REG_CURRENT_MSB, &raw); |
| 117 | if (err) | 135 | if (err) |
| 118 | return err; | 136 | return err; |
| 119 | *current_uA = raw * (DS2782_CURRENT_UNITS / sense_res); | 137 | *current_uA = raw * (DS2782_CURRENT_UNITS / sense_res); |
| 120 | return 0; | 138 | return 0; |
| 121 | } | 139 | } |
| 122 | 140 | ||
| 123 | static int ds2782_get_voltage(struct ds2782_info *info, int *voltage_uA) | 141 | static int ds2782_get_voltage(struct ds278x_info *info, int *voltage_uA) |
| 124 | { | 142 | { |
| 125 | s16 raw; | 143 | s16 raw; |
| 126 | int err; | 144 | int err; |
| @@ -129,36 +147,77 @@ static int ds2782_get_voltage(struct ds2782_info *info, int *voltage_uA) | |||
| 129 | * Voltage is measured in units of 4.88mV. The voltage is stored as | 147 | * Voltage is measured in units of 4.88mV. The voltage is stored as |
| 130 | * a 10-bit number plus sign, in the upper bits of a 16-bit register | 148 | * a 10-bit number plus sign, in the upper bits of a 16-bit register |
| 131 | */ | 149 | */ |
| 132 | err = ds2782_read_reg16(info, DS2782_REG_VOLT_MSB, &raw); | 150 | err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); |
| 133 | if (err) | 151 | if (err) |
| 134 | return err; | 152 | return err; |
| 135 | *voltage_uA = (raw / 32) * 4800; | 153 | *voltage_uA = (raw / 32) * 4800; |
| 136 | return 0; | 154 | return 0; |
| 137 | } | 155 | } |
| 138 | 156 | ||
| 139 | static int ds2782_get_capacity(struct ds2782_info *info, int *capac | ||
