1
/*
2
 * Driver for batteries with DS2746 chips inside.
3
 *
4
 * Copyright © 2009 Matthew Kern
5
 * 	       2007 Anton Vorontsov
6
 *	       2004-2007 Matt Reimer
7
 *	       2004 Szabolcs Gyurko
8
 *
9
 * Use consistent with the GNU GPL is permitted,
10
 * provided that this copyright notice is
11
 * preserved in its entirety in all copies and derived works.
12
 *
13
 * Author:  Matthew Kern <pyrophobicman@gmail.com
14
 * 	    January 2009
15
 *
16
 * 	    Anton Vorontsov <cbou@mail.ru>
17
 *	    February 2007
18
 *
19
 *	    Matt Reimer <mreimer@vpop.net>
20
 *	    April 2004, 2005, 2007
21
 *
22
 *	    Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
23
 *	    September 2004
24
 *
25
 *      Martin Johnson <m.j.johnson@massey.ac.nz>
26
 *      February 2009  - Simplified for HTC Kaiser 
27
 *	
28
 *	Stefan Seidel <kaiser@stefanseidel.info>
29
 *	March 2009 - Correct battery charge pctg. calculation
30
 */
31
32
/* I was originally writing this as a generic ds2746 driver, but there are too many kaiser-specific things, so... no. */
33
34
#include <linux/module.h>
35
#include <linux/param.h>
36
#include <linux/jiffies.h>
37
#include <linux/workqueue.h>
38
#include <linux/pm.h>
39
#include <linux/power_supply.h>
40
#include <linux/i2c.h>
41
#include <asm/gpio.h>
42
43
#ifdef CONFIG_ANDROID_POWER
44
#include <linux/android_power.h>
45
static android_suspend_lock_t vbus_suspend_lock;
46
#endif
47
48
49
/* definitions for registers we care about. */
50
#define DS2746_DATA_SIZE		0x12
51
52
#define DS2746_STATUS_REG		0x01
53
#define DS2746_AUX0_MSB			0x08
54
#define DS2746_AUX0_LSB			0x09
55
#define DS2746_AUX1_MSB			0x0a
56
#define DS2746_AUX1_LSB			0x0b
57
#define DS2746_VOLTAGE_MSB		0x0c
58
#define DS2746_VOLTAGE_LSB		0x0d
59
#define DS2746_CURRENT_MSB		0x0e
60
#define DS2746_CURRENT_LSB		0x0f
61
#define DS2746_CURRENT_ACCUM_MSB	0x10
62
#define DS2746_CURRENT_ACCUM_LSB	0x11
63
64
#define KAISER_RSNS			10 //in mOHM. From the maths, this should be correct
65
#define KAISER_BATTERY_RATING		2700 //in mAh - the standard battery (KAIS160) is this) 
66
67
68
struct i2c_client *pclient=0;
69
70
static int battery_capacity = KAISER_BATTERY_RATING;
71
module_param(battery_capacity, int, 0644);
72
MODULE_PARM_DESC(battery_capacity, "Estimated battery capacity in mAh");
73
74
static int i2c_read(int r) {
75
	unsigned char i2c_msg[1];
76
	unsigned char i2c_data[2];
77
	i2c_msg[0]=r;
78
	i2c_master_send(pclient, i2c_msg, 1);
79
	i2c_master_recv(pclient, i2c_data, 2);
80
//	printk("ds2746_i2c_read(%x)=%x %x\n",r,i2c_data[0],i2c_data[1]);
81
	return i2c_data[0];
82
}
83
84
static void i2c_write(int r, int v) {
85
	unsigned char i2c_msg[3];
86
	i2c_msg[0]=r;
87
	i2c_msg[1]=v>>8;
88
	i2c_msg[2]=v&0xFF;
89
	i2c_master_send(pclient, i2c_msg, 3);
90
}
91
92
static int reading2capacity(int r) {
93
    return (625L * r) / (100L * KAISER_RSNS);
94
}
95
96
static int capacity2reading(int c) {
97
    return (100L * c * KAISER_RSNS) / 625;
98
}
99
100
struct battery_info_reply {
101
	u32 batt_id;		/* Battery ID from ADC */
102
	u32 batt_vol;		/* Battery voltage from ADC */
103
	u32 batt_temp;		/* Battery Temperature (C) from formula and ADC */
104
	int batt_current;	/* Battery current from ADC */
105
	u32 level;		/* formula */
106
	u32 charging_source;	/* 0: no cable, 1:usb, 2:AC */
107
	u32 charging_enabled;	/* 0: Disable, 1: Enable */
108
	u32 full_bat;		/* Full capacity of battery (mAh) */
109
}; 
110
111
int ds2746_battery_read_status(struct battery_info_reply *b)
112
{
113
	short s;
114
	int aux0,aux1;
115
	int aux0r,aux1r;
116
117
	//	printk("read battery status\n");
118
	if(!pclient) {
119
		printk("client is null\n");
120
		b->level=50;
121
		return 0;
122
	}
123
124
	s=i2c_read(DS2746_VOLTAGE_LSB) | i2c_read(DS2746_VOLTAGE_MSB)<<8;
125
	b->batt_vol=((s>>4)*2440)/1000;
126
	
127
	s=i2c_read(DS2746_CURRENT_LSB) | i2c_read(DS2746_CURRENT_MSB)<<8;
128
	b->batt_current=((s>>2)*6250) / (KAISER_RSNS*1000);
129
	
130
	/* if battery voltage is < 3.3V and depleting, we assume it's almost empty! */
131
	if (b->batt_vol < 3300 && b->batt_current < 0) {
132
	    /* use approximate formula: 3.3V=5%, 3.0V=0% */
133
	    i2c_write(DS2746_CURRENT_ACCUM_MSB, 1L*battery_capacity*KAISER_RSNS*((5*b->batt_vol)/3-5000)/62500);
134
	}
135
	
136
	s=i2c_read(DS2746_CURRENT_ACCUM_LSB) | i2c_read(DS2746_CURRENT_ACCUM_MSB)<<8;
137
	
138
	if (s > 0) {
139
	    int max_seen_capacity = capacity2reading(battery_capacity);
140
	    if (s > max_seen_capacity) {
141
		/* if the battery is "fuller" than expected,
142
		* update our expectations */
143
		battery_capacity = reading2capacity(s);
144
	    } else {
145
		/* check if we're >4.2V and <5mA */
146
		if ((b->batt_vol >= 4200) && (b->batt_current < 5)) {
147
		  /* that's almost full, so let's assume it is
148
		   * (but leave 10mAh space to the max) */
149
		  battery_capacity = reading2capacity(s) + 10;
150
		}
151
	    }
152
	}
153
	
154
	// level = 100 * (s * 6.25 / (BATTERY_RATING * KAISER_RSNS))
155
	b->level=(s * 625) / (battery_capacity * KAISER_RSNS);
156
	/* if we read 0%, */
157
	if(b->level<1) {
158
	  /* only report 0% if we're really down, <3.1V */
159
	  b->level=((b->batt_vol <= 3100 )?0:1);
160
	}
161
	
162
	if(b->level>100) b->level=100;
163
	b->full_bat = 100;
164
	
165
	aux0 = i2c_read(DS2746_AUX0_LSB)>>4 | i2c_read(DS2746_AUX0_MSB)<<4;
166
	aux1 = i2c_read(DS2746_AUX1_LSB)>>4 | i2c_read(DS2746_AUX1_MSB)<<4;
167
	// ratio
168
	aux0r = (1000L*aux0)/2047;
169
	aux1r = (1000L*aux1)/2047;
170
	// resistance in Ohm (R_AUX=10kOhm)
171
	aux0r = (10000L*aux0r)/(1000-aux0r);
172
	aux1r = (10000L*aux1r)/(1000-aux1r);
173
	
174
	printk("ds2746: %dmV %dmA charge: %d/100 (%d units)\n        aux0: %d (%d) aux1: %d (%d)\n",b->batt_vol,b->batt_current,b->level,s,aux0,aux0r,aux1,aux1r);
175
	return 0;
176
}
177
178
static int ds2746_probe(struct i2c_client *client)
179
{
180
181
	printk("DS-2746 Probe\n");
182
	pclient = client;
183
	return 0;
184
}
185
186
static int ds2746_detach_client(struct i2c_client *client)
187
{
188
	i2c_detach_client(client);
189
	return 0;
190
}
191
192
193
static struct i2c_driver ds2746_battery_driver = {
194
	.probe	  = ds2746_probe,
195
	.remove   = ds2746_detach_client,
196
  .suspend  = NULL,
197
  .resume	  = NULL,
198
			.driver = {
199
		.name = "ds2746-battery",
200
	},
201
};
202
203
static int __init ds2746_battery_init(void)
204
{
205
206
#ifdef CONFIG_ANDROID_POWER
207
	vbus_suspend_lock.name = "vbus_present";
208
	android_init_suspend_lock(&vbus_suspend_lock);
209
#endif
210
	return i2c_add_driver(&ds2746_battery_driver);
211
}
212
213
static void __exit ds2746_battery_exit(void)
214
{
215
	i2c_del_driver(&ds2746_battery_driver);
216
}
217
218
module_init(ds2746_battery_init);
219
module_exit(ds2746_battery_exit);
220
221
MODULE_LICENSE("GPL");
222
MODULE_AUTHOR("Matthew Kern <pyrophobicman@gmail.com>, "
223
	      "Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
224
	      "Matt Reimer <mreimer@vpop.net>, "
225
	      "Anton Vorontsov <cbou@mail.ru>");
226
MODULE_DESCRIPTION("Battery driver for HTC kaiser");