aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/Kconfig14
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/ds2781_battery.c874
-rw-r--r--drivers/w1/slaves/Kconfig13
-rw-r--r--drivers/w1/slaves/Makefile1
-rw-r--r--drivers/w1/slaves/w1_ds2781.c201
-rw-r--r--drivers/w1/slaves/w1_ds2781.h136
-rw-r--r--drivers/w1/w1_family.h1
8 files changed, 1241 insertions, 0 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 3a8daf858742..459f66437fe9 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -76,6 +76,20 @@ config BATTERY_DS2780
76 help 76 help
77 Say Y here to enable support for batteries with ds2780 chip. 77 Say Y here to enable support for batteries with ds2780 chip.
78 78
79config BATTERY_DS2781
80 tristate "2781 battery driver"
81 depends on HAS_IOMEM
82 select W1
83 select W1_SLAVE_DS2781
84 help
85 If you enable this you will have the DS2781 battery driver support.
86
87 The battery monitor chip is used in many batteries/devices
88 as the one who is responsible for charging/discharging/monitoring
89 Li+ batteries.
90
91 If you are unsure, say N.
92
79config BATTERY_DS2782 93config BATTERY_DS2782
80 tristate "DS2782/DS2786 standalone gas-gauge" 94 tristate "DS2782/DS2786 standalone gas-gauge"
81 depends on I2C 95 depends on I2C
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index e429008eaf10..c590fa533406 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_TEST_POWER) += test_power.o
16 16
17obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o 17obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
18obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o 18obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
19obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
19obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o 20obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o
20obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o 21obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
21obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o 22obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c
new file mode 100644
index 000000000000..ca0d653d0a7a
--- /dev/null
+++ b/drivers/power/ds2781_battery.c
@@ -0,0 +1,874 @@
1/*
2 * 1-wire client/driver for the Maxim/Dallas DS2781 Stand-Alone Fuel Gauge IC
3 *
4 * Author: Renata Sayakhova <renata@oktetlabs.ru>
5 *
6 * Based on ds2780_battery drivers
7 *
8 * 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
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/param.h>
17#include <linux/pm.h>
18#include <linux/platform_device.h>
19#include <linux/power_supply.h>
20#include <linux/idr.h>
21
22#include "../w1/w1.h"
23#include "../w1/slaves/w1_ds2781.h"
24
25/* Current unit measurement in uA for a 1 milli-ohm sense resistor */
26#define DS2781_CURRENT_UNITS 1563
27/* Charge unit measurement in uAh for a 1 milli-ohm sense resistor */
28#define DS2781_CHARGE_UNITS 6250
29/* Number of bytes in user EEPROM space */
30#define DS2781_USER_EEPROM_SIZE (DS2781_EEPROM_BLOCK0_END - \
31 DS2781_EEPROM_BLOCK0_START + 1)
32/* Number of bytes in parameter EEPROM space */
33#define DS2781_PARAM_EEPROM_SIZE (DS2781_EEPROM_BLOCK1_END - \
34 DS2781_EEPROM_BLOCK1_START + 1)
35
36struct ds2781_device_info {
37 struct device *dev;
38 struct power_supply bat;
39 struct device *w1_dev;
40 struct task_struct *mutex_holder;
41};
42
43enum current_types {
44 CURRENT_NOW,
45 CURRENT_AVG,
46};
47
48static const char model[] = "DS2781";
49static const char manufacturer[] = "Maxim/Dallas";
50
51static inline struct ds2781_device_info *
52to_ds2781_device_info(struct power_supply *psy)
53{
54 return container_of(psy, struct ds2781_device_info, bat);
55}
56
57static inline struct power_supply *to_power_supply(struct device *dev)
58{
59 return dev_get_drvdata(dev);
60}
61
62static inline int ds2781_battery_io(struct ds2781_device_info *dev_info,
63 char *buf, int addr, size_t count, int io)
64{
65 if (dev_info->mutex_holder == current)
66 return w1_ds2781_io_nolock(dev_info->w1_dev, buf, addr,
67 count, io);
68 else
69 return w1_ds2781_io(dev_info->w1_dev, buf, addr, count, io);
70}
71
72int w1_ds2781_read(struct ds2781_device_info *dev_info, char *buf,
73 int addr, size_t count)
74{
75 return ds2781_battery_io(dev_info, buf, addr, count, 0);
76}
77
78static inline int ds2781_read8(struct ds2781_device_info *dev_info, u8 *val,
79 int addr)
80{
81 return ds2781_battery_io(dev_info, val, addr, sizeof(u8), 0);
82}
83
84static int ds2781_read16(struct ds2781_device_info *dev_info, s16 *val,
85 int addr)
86{
87 int ret;
88 u8 raw[2];
89
90 ret = ds2781_battery_io(dev_info, raw, addr, sizeof(raw), 0);
91 if (ret < 0)
92 return ret;
93
94 *val = (raw[0] << 8) | raw[1];
95
96 return 0;
97}
98
99static inline int ds2781_read_block(struct ds2781_device_info *dev_info,
100 u8 *val, int addr, size_t count)
101{
102 return ds2781_battery_io(dev_info, val, addr, count, 0);
103}
104
105static inline int ds2781_write(struct ds2781_device_info *dev_info, u8 *val,
106 int addr, size_t count)
107{
108 return ds2781_battery_io(dev_info, val, addr, count, 1);
109}
110
111static inline int ds2781_store_eeprom(struct device *dev, int addr)
112{
113 return w1_ds2781_eeprom_cmd(dev, addr, W1_DS2781_COPY_DATA);
114}
115
116static inline int ds2781_recall_eeprom(struct device *dev, int addr)
117{
118 return w1_ds2781_eeprom_cmd(dev, addr, W1_DS2781_RECALL_DATA);
119}
120
121static int ds2781_save_eeprom(struct ds2781_device_info *dev_info, int reg)
122{
123 int ret;
124
125 ret = ds2781_store_eeprom(dev_info->w1_dev, reg);
126 if (ret < 0)
127 return ret;
128
129 ret = ds2781_recall_eeprom(dev_info->w1_dev, reg);
130 if (ret < 0)
131 return ret;
132
133 return 0;
134}
135
136/* Set sense resistor value in mhos */
137static int ds2781_set_sense_register(struct ds2781_device_info *dev_info,
138 u8 conductance)
139{
140 int ret;
141
142 ret = ds2781_write(dev_info, &conductance,
143 DS2781_RSNSP, sizeof(u8));
144 if (ret < 0)
145 return ret;
146
147 return ds2781_save_eeprom(dev_info, DS2781_RSNSP);
148}
149
150/* Get RSGAIN value from 0 to 1.999 in steps of 0.001 */
151static int ds2781_get_rsgain_register(struct ds2781_device_info *dev_info,
152 u16 *rsgain)
153{
154 return ds2781_read16(dev_info, rsgain, DS2781_RSGAIN_MSB);
155}
156
157/* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */
158static int ds2781_set_rsgain_register(struct ds2781_device_info *dev_info,
159 u16 rsgain)
160{
161 int ret;
162 u8 raw[] = {rsgain >> 8, rsgain & 0xFF};
163
164 ret = ds2781_write(dev_info, raw,
165 DS2781_RSGAIN_MSB, sizeof(raw));
166 if (ret < 0)
167 return ret;
168
169 return ds2781_save_eeprom(dev_info, DS2781_RSGAIN_MSB);
170}
171
172static int ds2781_get_voltage(struct ds2781_device_info *dev_info,
173 int *voltage_uV)
174{
175 int ret;
176 char val[2];
177 int voltage_raw;
178
179 ret = w1_ds2781_read(dev_info, val, DS2781_VOLT_MSB, 2 * sizeof(u8));
180 if (ret < 0)
181 return ret;
182 /*
183 * The voltage value is located in 10 bits across the voltage MSB
184 * and LSB registers in two's compliment form
185 * Sign bit of the voltage value is in bit 7 of the voltage MSB register
186 * Bits 9 - 3 of the voltage value are in bits 6 - 0 of the
187 * voltage MSB register
188 * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the
189 * voltage LSB register
190 */
191 voltage_raw = (val[0] << 3) |
192 (val[1] >> 5);
193
194 /* DS2781 reports voltage in units of 9.76mV, but the battery class
195 * reports in units of uV, so convert by multiplying by 9760. */
196 *voltage_uV = voltage_raw * 9760;
197
198 return 0;
199}
200
201static int ds2781_get_temperature(struct ds2781_device_info *dev_info,
202 int *temp)
203{
204 int ret;
205 char val[2];
206 int temp_raw;
207
208 ret = w1_ds2781_read(dev_info, val, DS2781_TEMP_MSB, 2 * sizeof(u8));
209 if (ret < 0)
210 return ret;
211 /*
212 * The temperature value is located in 10 bits across the temperature
213 * MSB and LSB registers in two's compliment form
214 * Sign bit of the temperature value is in bit 7 of the temperature
215 * MSB register
216 * Bits 9 - 3 of the temperature value are in bits 6 - 0 of the
217 * temperature MSB register
218 * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the
219 * temperature LSB register
220 */
221 temp_raw = ((val[0]) << 3) |
222 (val[1] >> 5);
223 *temp = temp_raw + (temp_raw / 4);
224
225 return 0;
226}
227
228static int ds2781_get_current(struct ds2781_device_info *dev_info,
229 enum current_types type, int *current_uA)
230{
231 int ret, sense_res;
232 s16 current_raw;
233 u8 sense_res_raw, reg_msb;
234
235 /*
236 * The units of measurement for current are dependent on the value of
237 * the sense resistor.
238 */
239 ret = ds2781_read8(dev_info, &sense_res_raw, DS2781_RSNSP);
240 if (ret < 0)
241 return ret;
242
243 if (sense_res_raw == 0) {
244 dev_err(dev_info->dev, "sense resistor value is 0\n");
245 return -EINVAL;
246 }
247 sense_res = 1000 / sense_res_raw;
248
249 if (type == CURRENT_NOW)
250 reg_msb = DS2781_CURRENT_MSB;
251 else if (type == CURRENT_AVG)
252 reg_msb = DS2781_IAVG_MSB;
253 else
254 return -EINVAL;
255
256 /*
257 * The current value is located in 16 bits across the current MSB
258 * and LSB registers in two's compliment form
259 * Sign bit of the current value is in bit 7 of the current MSB register
260 * Bits 14 - 8 of the current value are in bits 6 - 0 of the current
261 * MSB register
262 * Bits 7 - 0 of the current value are in bits 7 - 0 of the current
263 * LSB register
264 */
265 ret = ds2781_read16(dev_info, &current_raw, reg_msb);
266 if (ret < 0)
267 return ret;
268
269 *current_uA = current_raw * (DS2781_CURRENT_UNITS / sense_res);
270 return 0;
271}
272
273static int ds2781_get_accumulated_current(struct ds2781_device_info *dev_info,
274 int *accumulated_current)
275{
276 int ret, sense_res;
277 s16 current_raw;
278 u8 sense_res_raw;
279
280 /*
281 * The units of measurement for accumulated current are dependent on
282 * the value of the sense resistor.
283 */
284 ret = ds2781_read8(dev_info, &sense_res_raw, DS2781_RSNSP);
285 if (ret < 0)
286 return ret;
287
288 if (sense_res_raw == 0) {
289 dev_err(dev_info->dev, "sense resistor value is 0\n");
290 return -EINVAL;
291 }
292 sense_res = 1000 / sense_res_raw;
293
294 /*
295 * The ACR value is located in 16 bits across the ACR MSB and
296 * LSB registers
297 * Bits 15 - 8 of the ACR value are in bits 7 - 0 of the ACR
298 * MSB register
299 * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR
300 * LSB register
301 */
302 ret = ds2781_read16(dev_info, &current_raw, DS2781_ACR_MSB);
303 if (ret < 0)
304 return ret;
305
306 *accumulated_current = current_raw * (DS2781_CHARGE_UNITS / sense_res);
307 return 0;
308}
309
310static int ds2781_get_capacity(struct ds2781_device_info *dev_info,
311 int *capacity)
312{
313 int ret;
314 u8 raw;
315
316 ret = ds2781_read8(dev_info, &raw, DS2781_RARC);
317 if (ret < 0)
318 return ret;
319
320 *capacity = raw;
321 return 0;
322}
323
324static int ds2781_get_status(struct ds2781_device_info *dev_info, int *status)
325{
326 int ret, current_uA, capacity;
327
328 ret = ds2781_get_current(dev_info, CURRENT_NOW, &current_uA);
329 if (ret < 0)
330 return ret;
331
332 ret = ds2781_get_capacity(dev_info, &capacity);
333 if (ret < 0)
334 return ret;
335
336 if (power_supply_am_i_supplied(&dev_info->bat)) {
337 if (capacity == 100)
338 *status = POWER_SUPPLY_STATUS_FULL;
339 else if (current_uA > 50000)
340 *status = POWER_SUPPLY_STATUS_CHARGING;
341 else
342 *status = POWER_SUPPLY_STATUS_NOT_CHARGING;
343 } else {
344 *status = POWER_SUPPLY_STATUS_DISCHARGING;
345 }
346 return 0;
347}
348
349static int ds2781_get_charge_now(struct ds2781_device_info *dev_info,
350 int *charge_now)
351{
352 int ret;
353 u16 charge_raw;
354
355 /*
356 * The RAAC value is located in 16 bits across the RAAC MSB and
357 * LSB registers
358 * Bits 15 - 8 of the RAAC value are in bits 7 - 0 of the RAAC
359 * MSB register
360 * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC
361 * LSB register
362 */
363 ret = ds2781_read16(dev_info, &charge_raw, DS2781_RAAC_MSB);
364 if (ret < 0)
365 return ret;
366
367 *charge_now = charge_raw * 1600;
368 return 0;
369}
370
371static int ds2781_get_control_register(struct ds2781_device_info *dev_info,
372 u8 *control_reg)
373{
374 return ds2781_read8(dev_info, control_reg, DS2781_CONTROL);
375}
376
377static int ds2781_set_control_register(struct ds2781_device_info *dev_info,
378 u8 control_reg)
379{
380 int ret;
381
382 ret = ds2781_write(dev_info, &control_reg,
383 DS2781_CONTROL, sizeof(u8));
384 if (ret < 0)
385 return ret;
386
387 return ds2781_save_eeprom(dev_info, DS2781_CONTROL);
388}
389
390static int ds2781_battery_get_property(struct power_supply *psy,
391 enum power_supply_property psp,
392 union power_supply_propval *val)
393{
394 int ret = 0;
395 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
396
397 switch (psp) {
398 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
399 ret = ds2781_get_voltage(dev_info, &val->intval);
400 break;
401
402 case POWER_SUPPLY_PROP_TEMP:
403 ret = ds2781_get_temperature(dev_info, &val->intval);
404 break;
405
406 case POWER_SUPPLY_PROP_MODEL_NAME:
407 val->strval = model;
408 break;
409
410 case POWER_SUPPLY_PROP_MANUFACTURER:
411 val->strval = manufacturer;
412 break;
413
414 case POWER_SUPPLY_PROP_CURRENT_NOW:
415 ret = ds2781_get_current(dev_info, CURRENT_NOW, &val->intval);
416 break;
417
418 case POWER_SUPPLY_PROP_CURRENT_AVG:
419 ret = ds2781_get_current(dev_info, CURRENT_AVG, &val->intval);
420 break;
421
422 case POWER_SUPPLY_PROP_STATUS:
423 ret = ds2781_get_status(dev_info, &val->intval);
424 break;
425
426 case POWER_SUPPLY_PROP_CAPACITY:
427 ret = ds2781_get_capacity(dev_info, &val->intval);
428 break;
429
430 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
431 ret = ds2781_get_accumulated_current(dev_info, &val->intval);
432 break;
433
434 case POWER_SUPPLY_PROP_CHARGE_NOW:
435 ret = ds2781_get_charge_now(dev_info, &val->intval);
436 break;
437
438 default:
439 ret = -EINVAL;
440 }
441
442 return ret;
443}
444
445static enum power_supply_property ds2781_battery_props[] = {
446 POWER_SUPPLY_PROP_STATUS,
447 POWER_SUPPLY_PROP_VOLTAGE_NOW,
448 POWER_SUPPLY_PROP_TEMP,
449 POWER_SUPPLY_PROP_MODEL_NAME,
450 POWER_SUPPLY_PROP_MANUFACTURER,
451 POWER_SUPPLY_PROP_CURRENT_NOW,
452 POWER_SUPPLY_PROP_CURRENT_AVG,
453 POWER_SUPPLY_PROP_CAPACITY,
454 POWER_SUPPLY_PROP_CHARGE_COUNTER,
455 POWER_SUPPLY_PROP_CHARGE_NOW,
456};
457
458static ssize_t ds2781_get_pmod_enabled(struct device *dev,
459 struct device_attribute *attr,
460 char *buf)
461{
462 int ret;
463 u8 control_reg;
464 struct power_supply *psy = to_power_supply(dev);
465 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
466
467 /* Get power mode */
468 ret = ds2781_get_control_register(dev_info, &control_reg);
469 if (ret < 0)
470 return ret;
471
472 return sprintf(buf, "%d\n",
473 !!(control_reg & DS2781_CONTROL_PMOD));
474}
475
476static ssize_t ds2781_set_pmod_enabled(struct device *dev,
477 struct device_attribute *attr,
478 const char *buf,
479 size_t count)
480{
481 int ret;
482 u8 control_reg, new_setting;
483 struct power_supply *psy = to_power_supply(dev);
484 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
485
486 /* Set power mode */
487 ret = ds2781_get_control_register(dev_info, &control_reg);
488 if (ret < 0)
489 return ret;
490
491 ret = kstrtou8(buf, 0, &new_setting);
492 if (ret < 0)
493 return ret;
494
495 if ((new_setting != 0) && (new_setting != 1)) {
496 dev_err(dev_info->dev, "Invalid pmod setting (0 or 1)\n");
497 return -EINVAL;
498 }
499
500 if (new_setting)
501 control_reg |= DS2781_CONTROL_PMOD;
502 else
503 control_reg &= ~DS2781_CONTROL_PMOD;
504
505 ret = ds2781_set_control_register(dev_info, control_reg);
506 if (ret < 0)
507 return ret;
508
509 return count;
510}
511
512static ssize_t ds2781_get_sense_resistor_value(struct device *dev,
513 struct device_attribute *attr,
514 char *buf)
515{
516 int ret;
517 u8 sense_resistor;
518 struct power_supply *psy = to_power_supply(dev);
519 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
520
521 ret = ds2781_read8(dev_info, &sense_resistor, DS2781_RSNSP);
522 if (ret < 0)
523 return ret;
524
525 ret = sprintf(buf, "%d\n", sense_resistor);
526 return ret;
527}
528
529static ssize_t ds2781_set_sense_resistor_value(struct device *dev,
530 struct device_attribute *attr,
531 const char *buf,
532 size_t count)
533{
534 int ret;
535 u8 new_setting;
536 struct power_supply *psy = to_power_supply(dev);
537 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
538
539 ret = kstrtou8(buf, 0, &new_setting);
540 if (ret < 0)
541 return ret;
542
543 ret = ds2781_set_sense_register(dev_info, new_setting);
544 if (ret < 0)
545 return ret;
546
547 return count;
548}
549
550static ssize_t ds2781_get_rsgain_setting(struct device *dev,
551 struct device_attribute *attr,
552 char *buf)
553{
554 int ret;
555 u16 rsgain;
556 struct power_supply *psy = to_power_supply(dev);
557 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
558
559 ret = ds2781_get_rsgain_register(dev_info, &rsgain);
560 if (ret < 0)
561 return ret;
562
563 return sprintf(buf, "%d\n", rsgain);
564}
565
566static ssize_t ds2781_set_rsgain_setting(struct device *dev,
567 struct device_attribute *attr,
568 const char *buf,
569 size_t count)
570{
571 int ret;
572 u16 new_setting;
573 struct power_supply *psy = to_power_supply(dev);
574 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
575
576 ret = kstrtou16(buf, 0, &new_setting);
577 if (ret < 0)
578 return ret;
579
580 /* Gain can only be from 0 to 1.999 in steps of .001 */
581 if (new_setting > 1999) {
582 dev_err(dev_info->dev, "Invalid rsgain setting (0 - 1999)\n");
583 return -EINVAL;
584 }
585
586 ret = ds2781_set_rsgain_register(dev_info, new_setting);
587 if (ret < 0)
588 return ret;
589
590 return count;
591}
592
593static ssize_t ds2781_get_pio_pin(struct device *dev,
594 struct device_attribute *attr,
595 char *buf)
596{
597 int ret;
598 u8 sfr;
599 struct power_supply *psy = to_power_supply(dev);
600 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
601
602 ret = ds2781_read8(dev_info, &sfr, DS2781_SFR);
603 if (ret < 0)
604 return ret;
605
606 ret = sprintf(buf, "%d\n", sfr & DS2781_SFR_PIOSC);
607 return ret;
608}
609
610static ssize_t ds2781_set_pio_pin(struct device *dev,
611 struct device_attribute *attr,
612 const char *buf,
613 size_t count)
614{
615 int ret;
616 u8 new_setting;
617 struct power_supply *psy = to_power_supply(dev);
618 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
619
620 ret = kstrtou8(buf, 0, &new_setting);
621 if (ret < 0)
622 return ret;
623
624 if ((new_setting != 0) && (new_setting != 1)) {
625 dev_err(dev_info->dev, "Invalid pio_pin setting (0 or 1)\n");
626 return -EINVAL;
627 }
628
629 ret = ds2781_write(dev_info, &new_setting,
630 DS2781_SFR, sizeof(u8));
631 if (ret < 0)
632 return ret;
633
634 return count;
635}
636
637static ssize_t ds2781_read_param_eeprom_bin(struct file *filp,
638 struct kobject *kobj,
639 struct bin_attribute *bin_attr,
640 char *buf, loff_t off, size_t count)
641{
642 struct device *dev = container_of(kobj, struct device, kobj);
643 struct power_supply *psy = to_power_supply(dev);
644 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
645
646 count = min_t(loff_t, count,
647 DS2781_EEPROM_BLOCK1_END -
648 DS2781_EEPROM_BLOCK1_START + 1 - off);
649
650 return ds2781_read_block(dev_info, buf,
651 DS2781_EEPROM_BLOCK1_START + off, count);
652}
653
654static ssize_t ds2781_write_param_eeprom_bin(struct file *filp,
655 struct kobject *kobj,
656 struct bin_attribute *bin_attr,
657 char *buf, loff_t off, size_t count)
658{
659 struct device *dev = container_of(kobj, struct device, kobj);
660 struct power_supply *psy = to_power_supply(dev);
661 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
662 int ret;
663
664 count = min_t(loff_t, count,
665 DS2781_EEPROM_BLOCK1_END -
666 DS2781_EEPROM_BLOCK1_START + 1 - off);
667
668 ret = ds2781_write(dev_info, buf,
669 DS2781_EEPROM_BLOCK1_START + off, count);
670 if (ret < 0)
671 return ret;
672
673 ret = ds2781_save_eeprom(dev_info, DS2781_EEPROM_BLOCK1_START);
674 if (ret < 0)
675 return ret;
676
677 return count;
678}
679
680static struct bin_attribute ds2781_param_eeprom_bin_attr = {
681 .attr = {
682 .name = "param_eeprom",
683 .mode = S_IRUGO | S_IWUSR,
684 },
685 .size = DS2781_EEPROM_BLOCK1_END - DS2781_EEPROM_BLOCK1_START + 1,
686 .read = ds2781_read_param_eeprom_bin,
687 .write = ds2781_write_param_eeprom_bin,
688};
689
690static ssize_t ds2781_read_user_eeprom_bin(struct file *filp,
691 struct kobject *kobj,
692 struct bin_attribute *bin_attr,
693 char *buf, loff_t off, size_t count)
694{
695 struct device *dev = container_of(kobj, struct device, kobj);
696 struct power_supply *psy = to_power_supply(dev);
697 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
698
699 count = min_t(loff_t, count,
700 DS2781_EEPROM_BLOCK0_END -
701 DS2781_EEPROM_BLOCK0_START + 1 - off);
702
703 return ds2781_read_block(dev_info, buf,
704 DS2781_EEPROM_BLOCK0_START + off, count);
705
706}
707
708static ssize_t ds2781_write_user_eeprom_bin(struct file *filp,
709 struct kobject *kobj,
710 struct bin_attribute *bin_attr,
711 char *buf, loff_t off, size_t count)
712{
713 struct device *dev = container_of(kobj, struct device, kobj);
714 struct power_supply *psy = to_power_supply(dev);
715 struct ds2781_device_info *dev_info = to_ds2781_device_info(psy);
716 int ret;
717
718 count = min_t(loff_t, count,
719 DS2781_EEPROM_BLOCK0_END -
720 DS2781_EEPROM_BLOCK0_START + 1 - off);
721
722 ret = ds2781_write(dev_info, buf,
723 DS2781_EEPROM_BLOCK0_START + off, count);
724 if (ret < 0)
725 return ret;
726
727 ret = ds2781_save_eeprom(dev_info, DS2781_EEPROM_BLOCK0_START);
728 if (ret < 0)
729 return ret;
730
731 return count;
732}
733
734static struct bin_attribute ds2781_user_eeprom_bin_attr = {
735 .attr = {
736 .name = "user_eeprom",
737 .mode = S_IRUGO | S_IWUSR,
738 },
739 .size = DS2781_EEPROM_BLOCK0_END - DS2781_EEPROM_BLOCK0_START + 1,
740 .read = ds2781_read_user_eeprom_bin,
741 .write = ds2781_write_user_eeprom_bin,
742};
743
744static DEVICE_ATTR(pmod_enabled, S_IRUGO | S_IWUSR, ds2781_get_pmod_enabled,
745 ds2781_set_pmod_enabled);
746static DEVICE_ATTR(sense_resistor_value, S_IRUGO | S_IWUSR,
747 ds2781_get_sense_resistor_value, ds2781_set_sense_resistor_value);
748static DEVICE_ATTR(rsgain_setting, S_IRUGO | S_IWUSR, ds2781_get_rsgain_setting,
749 ds2781_set_rsgain_setting);
750static DEVICE_ATTR(pio_pin, S_IRUGO | S_IWUSR, ds2781_get_pio_pin,
751 ds2781_set_pio_pin);
752
753
754static struct attribute *ds2781_attributes[] = {
755 &dev_attr_pmod_enabled.attr,
756 &dev_attr_sense_resistor_value.attr,
757 &dev_attr_rsgain_setting.attr,
758 &dev_attr_pio_pin.attr,
759 NULL
760};
761
762static const struct attribute_group ds2781_attr_group = {
763 .attrs = ds2781_attributes,
764};
765
766static int __devinit ds2781_battery_probe(struct platform_device *pdev)
767{
768 int ret = 0;
769 struct ds2781_device_info *dev_info;
770
771 dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
772 if (!dev_info) {
773 ret = -ENOMEM;
774 goto fail;
775 }
776
777 platform_set_drvdata(pdev, dev_info);
778
779 dev_info->dev = &pdev->dev;
780 dev_info->w1_dev = pdev->dev.parent;
781 dev_info->bat.name = dev_name(&pdev->dev);
782 dev_info->bat.type = POWER_SUPPLY_TYPE_BATTERY;
783 dev_info->bat.properties = ds2781_battery_props;
784 dev_info->bat.num_properties = ARRAY_SIZE(ds2781_battery_props);
785 dev_info->bat.get_property = ds2781_battery_get_property;
786 dev_info->mutex_holder = current;
787
788 ret = power_supply_register(&pdev->dev, &dev_info->bat);
789 if (ret) {
790 dev_err(dev_info->dev, "failed to register battery\n");
791 goto fail_free_info;
792 }
793
794 ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2781_attr_group);
795 if (ret) {
796 dev_err(dev_info->dev, "failed to create sysfs group\n");
797 goto fail_unregister;
798 }
799
800 ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj,
801 &ds2781_param_eeprom_bin_attr);
802 if (ret) {
803 dev_err(dev_info->dev,
804 "failed to create param eeprom bin file");
805 goto fail_remove_group;
806 }
807
808 ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj,
809 &ds2781_user_eeprom_bin_attr);
810 if (ret) {
811 dev_err(dev_info->dev,
812 "failed to create user eeprom bin file");
813 goto fail_remove_bin_file;
814 }
815
816 dev_info->mutex_holder = NULL;
817
818 return 0;
819
820fail_remove_bin_file:
821 sysfs_remove_bin_file(&dev_info->bat.dev->kobj,
822 &ds2781_param_eeprom_bin_attr);
823fail_remove_group:
824 sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group);
825fail_unregister:
826 power_supply_unregister(&dev_info->bat);
827fail_free_info:
828 kfree(dev_info);
829fail:
830 return ret;
831}
832
833static int __devexit ds2781_battery_remove(struct platform_device *pdev)
834{
835 struct ds2781_device_info *dev_info = platform_get_drvdata(pdev);
836
837 dev_info->mutex_holder = current;
838
839 /* remove attributes */
840 sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group);
841
842 power_supply_unregister(&dev_info->bat);
843
844 kfree(dev_info);
845 return 0;
846}
847
848static struct platform_driver ds2781_battery_driver = {
849 .driver = {
850 .name = "ds2781-battery",
851 },
852 .probe = ds2781_battery_probe,
853 .remove = __devexit_p(ds2781_battery_remove),
854};
855
856static int __init ds2781_battery_init(void)
857{
858 return platform_driver_register(&ds2781_battery_driver);
859}
860
861static void __exit ds2781_battery_exit(void)
862{
863 platform_driver_unregister(&ds2781_battery_driver);
864}
865
866module_init(ds2781_battery_init);
867module_exit(ds2781_battery_exit);
868
869
870MODULE_LICENSE("GPL");
871MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>");
872MODULE_DESCRIPTION("Maxim/Dallas DS2781 Stand-Alone Fuel Gauage IC driver");
873MODULE_ALIAS("platform:ds2781-battery");
874
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index d0cb01b42012..eb9e376d6244 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -81,6 +81,19 @@ config W1_SLAVE_DS2780
81 81
82 If you are unsure, say N. 82 If you are unsure, say N.
83 83
84config W1_SLAVE_DS2781
85 tristate "Dallas 2781 battery monitor chip"
86 depends on W1
87 help
88 If you enable this you will have the DS2781 battery monitor
89 chip support.
90
91 The battery monitor chip is used in many batteries/devices
92 as the one who is responsible for charging/discharging/monitoring
93 Li+ batteries.
94
95 If you are unsure, say N.
96
84config W1_SLAVE_BQ27000 97config W1_SLAVE_BQ27000
85 tristate "BQ27000 slave support" 98 tristate "BQ27000 slave support"
86 depends on W1 99 depends on W1
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index 1f31e9fb0b25..c4f1859fb520 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o
10obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o 10obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
11obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o 11obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
12obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o 12obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o
13obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o
13obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o 14obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o
diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c
new file mode 100644
index 000000000000..0d0c7985293f
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2781.c
@@ -0,0 +1,201 @@
1/*
2 * 1-Wire implementation for the ds2781 chip
3 *
4 * Author: Renata Sayakhova <renata@oktetlabs.ru>
5 *
6 * Based on w1-ds2780 driver
7 *
8 * 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
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/types.h>
18#include <linux/platform_device.h>
19#include <linux/mutex.h>
20#include <linux/idr.h>
21
22#include "../w1.h"
23#include "../w1_int.h"
24#include "../w1_family.h"
25#include "w1_ds2781.h"
26
27static int w1_ds2781_do_io(struct device *dev, char *buf, int addr,
28 size_t count, int io)
29{
30 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
31
32 if (addr > DS2781_DATA_SIZE || addr < 0)
33 return 0;
34
35 count = min_t(int, count, DS2781_DATA_SIZE - addr);
36
37 if (w1_reset_select_slave(sl) == 0) {
38 if (io) {
39 w1_write_8(sl->master, W1_DS2781_WRITE_DATA);
40 w1_write_8(sl->master, addr);
41 w1_write_block(sl->master, buf, count);
42 } else {
43 w1_write_8(sl->master, W1_DS2781_READ_DATA);
44 w1_write_8(sl->master, addr);
45 count = w1_read_block(sl->master, buf, count);
46 }
47 }
48
49 return count;
50}
51
52int w1_ds2781_io(struct device *dev, char *buf, int addr, size_t count,
53 int io)
54{
55 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
56 int ret;
57
58 if (!dev)
59 return -ENODEV;
60
61 mutex_lock(&sl->master->mutex);
62
63 ret = w1_ds2781_do_io(dev, buf, addr, count, io);
64
65 mutex_unlock(&sl->master->mutex);
66
67 return ret;
68}
69EXPORT_SYMBOL(w1_ds2781_io);
70
71int w1_ds2781_io_nolock(struct device *dev, char *buf, int addr, size_t count,
72 int io)
73{
74 int ret;
75
76 if (!dev)
77 return -ENODEV;
78
79 ret = w1_ds2781_do_io(dev, buf, addr, count, io);
80
81 return ret;
82}
83EXPORT_SYMBOL(w1_ds2781_io_nolock);
84
85int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd)
86{
87 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
88
89 if (!dev)
90 return -EINVAL;
91
92 mutex_lock(&sl->master->mutex);
93
94 if (w1_reset_select_slave(sl) == 0) {
95 w1_write_8(sl->master, cmd);
96 w1_write_8(sl->master, addr);
97 }
98
99 mutex_unlock(&sl->master->mutex);
100 return 0;
101}
102EXPORT_SYMBOL(w1_ds2781_eeprom_cmd);
103
104static ssize_t w1_ds2781_read_bin(struct file *filp,
105 struct kobject *kobj,
106 struct bin_attribute *bin_attr,
107 char *buf, loff_t off, size_t count)
108{
109 struct device *dev = container_of(kobj, struct device, kobj);
110 return w1_ds2781_io(dev, buf, off, count, 0);
111}
112
113static struct bin_attribute w1_ds2781_bin_attr = {
114 .attr = {
115 .name = "w1_slave",
116 .mode = S_IRUGO,
117 },
118 .size = DS2781_DATA_SIZE,
119 .read = w1_ds2781_read_bin,
120};
121
122static DEFINE_IDA(bat_ida);
123
124static int w1_ds2781_add_slave(struct w1_slave *sl)
125{
126 int ret;
127 int id;
128 struct platform_device *pdev;
129
130 id = ida_simple_get(&bat_ida, 0, 0, GFP_KERNEL);
131 if (id < 0) {
132 ret = id;
133 goto noid;
134 }
135
136 pdev = platform_device_alloc("ds2781-battery", id);
137 if (!pdev) {
138 ret = -ENOMEM;
139 goto pdev_alloc_failed;
140 }
141 pdev->dev.parent = &sl->dev;
142
143 ret = platform_device_add(pdev);
144 if (ret)
145 goto pdev_add_failed;
146
147 ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr);
148 if (ret)
149 goto bin_attr_failed;
150
151 dev_set_drvdata(&sl->dev, pdev);
152
153 return 0;
154
155bin_attr_failed:
156pdev_add_failed:
157 platform_device_unregister(pdev);
158pdev_alloc_failed:
159 ida_simple_remove(&bat_ida, id);
160noid:
161 return ret;
162}
163
164static void w1_ds2781_remove_slave(struct w1_slave *sl)
165{
166 struct platform_device *pdev = dev_get_drvdata(&sl->dev);
167 int id = pdev->id;
168
169 platform_device_unregister(pdev);
170 ida_simple_remove(&bat_ida, id);
171 sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr);
172}
173
174static struct w1_family_ops w1_ds2781_fops = {
175 .add_slave = w1_ds2781_add_slave,
176 .remove_slave = w1_ds2781_remove_slave,
177};
178
179static struct w1_family w1_ds2781_family = {
180 .fid = W1_FAMILY_DS2781,
181 .fops = &w1_ds2781_fops,
182};
183
184static int __init w1_ds2781_init(void)
185{
186 ida_init(&bat_ida);
187 return w1_register_family(&w1_ds2781_family);
188}
189
190static void __exit w1_ds2781_exit(void)
191{
192 w1_unregister_family(&w1_ds2781_family);
193 ida_destroy(&bat_ida);
194}
195
196module_init(w1_ds2781_init);
197module_exit(w1_ds2781_exit);
198
199MODULE_LICENSE("GPL");
200MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>");
201MODULE_DESCRIPTION("1-wire Driver for Maxim/Dallas DS2781 Stand-Alone Fuel Gauge IC");
diff --git a/drivers/w1/slaves/w1_ds2781.h b/drivers/w1/slaves/w1_ds2781.h
new file mode 100644
index 000000000000..82bc66497b43
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2781.h
@@ -0,0 +1,136 @@
1/*
2 * 1-Wire implementation for the ds2780 chip
3 *
4 * Author: Renata Sayakhova <renata@oktetlabs.ru>
5 *
6 * Based on w1-ds2760 driver
7 *
8 * 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
10 * published by the Free Software Foundation.
11 *
12 */
13
14#ifndef _W1_DS2781_H
15#define _W1_DS2781_H
16
17/* Function commands */
18#define W1_DS2781_READ_DATA 0x69
19#define W1_DS2781_WRITE_DATA 0x6C
20#define W1_DS2781_COPY_DATA 0x48
21#define W1_DS2781_RECALL_DATA 0xB8
22#define W1_DS2781_LOCK 0x6A
23
24/* Register map */
25/* Register 0x00 Reserved */
26#define DS2781_STATUS 0x01
27#define DS2781_RAAC_MSB 0x02
28#define DS2781_RAAC_LSB 0x03
29#define DS2781_RSAC_MSB 0x04
30#define DS2781_RSAC_LSB 0x05
31#define DS2781_RARC 0x06
32#define DS2781_RSRC 0x07
33#define DS2781_IAVG_MSB 0x08
34#define DS2781_IAVG_LSB 0x09
35#define DS2781_TEMP_MSB 0x0A
36#define DS2781_TEMP_LSB 0x0B
37#define DS2781_VOLT_MSB 0x0C
38#define DS2781_VOLT_LSB 0x0D
39#define DS2781_CURRENT_MSB 0x0E
40#define DS2781_CURRENT_LSB 0x0F
41#define DS2781_ACR_MSB 0x10
42#define DS2781_ACR_LSB 0x11
43#define DS2781_ACRL_MSB 0x12
44#define DS2781_ACRL_LSB 0x13
45#define DS2781_AS 0x14
46#define DS2781_SFR 0x15
47#define DS2781_FULL_MSB 0x16
48#define DS2781_FULL_LSB 0x17
49#define DS2781_AE_MSB 0x18
50#define DS2781_AE_LSB 0x19
51#define DS2781_SE_MSB 0x1A
52#define DS2781_SE_LSB 0x1B
53/* Register 0x1C - 0x1E Reserved */
54#define DS2781_EEPROM 0x1F
55#define DS2781_EEPROM_BLOCK0_START 0x20
56/* Register 0x20 - 0x2F User EEPROM */
57#define DS2781_EEPROM_BLOCK0_END 0x2F
58/* Register 0x30 - 0x5F Reserved */
59#define DS2781_EEPROM_BLOCK1_START 0x60
60#define DS2781_CONTROL 0x60
61#define DS2781_AB 0x61
62#define DS2781_AC_MSB 0x62
63#define DS2781_AC_LSB 0x63
64#define DS2781_VCHG 0x64
65#define DS2781_IMIN 0x65
66#define DS2781_VAE 0x66
67#define DS2781_IAE 0x67
68#define DS2781_AE_40 0x68
69#define DS2781_RSNSP 0x69
70#define DS2781_FULL_40_MSB 0x6A
71#define DS2781_FULL_40_LSB 0x6B
72#define DS2781_FULL_4_SLOPE 0x6C
73#define DS2781_FULL_3_SLOPE 0x6D
74#define DS2781_FULL_2_SLOPE 0x6E
75#define DS2781_FULL_1_SLOPE 0x6F
76#define DS2781_AE_4_SLOPE 0x70
77#define DS2781_AE_3_SLOPE 0x71
78#define DS2781_AE_2_SLOPE 0x72
79#define DS2781_AE_1_SLOPE 0x73
80#define DS2781_SE_4_SLOPE 0x74
81#define DS2781_SE_3_SLOPE 0x75
82#define DS2781_SE_2_SLOPE 0x76
83#define DS2781_SE_1_SLOPE 0x77
84#define DS2781_RSGAIN_MSB 0x78
85#define DS2781_RSGAIN_LSB 0x79
86#define DS2781_RSTC 0x7A
87#define DS2781_COB 0x7B
88#define DS2781_TBP34 0x7C
89#define DS2781_TBP23 0x7D
90#define DS2781_TBP12 0x7E
91#define DS2781_EEPROM_BLOCK1_END 0x7F
92/* Register 0x7D - 0xFF Reserved */
93
94#define DS2781_FSGAIN_MSB 0xB0
95#define DS2781_FSGAIN_LSB 0xB1
96
97/* Number of valid register addresses */
98#define DS2781_DATA_SIZE 0xB2
99
100/* Status register bits */
101#define DS2781_STATUS_CHGTF (1 << 7)
102#define DS2781_STATUS_AEF (1 << 6)
103#define DS2781_STATUS_SEF (1 << 5)
104#define DS2781_STATUS_LEARNF (1 << 4)
105/* Bit 3 Reserved */
106#define DS2781_STATUS_UVF (1 << 2)
107#define DS2781_STATUS_PORF (1 << 1)
108/* Bit 0 Reserved */
109
110/* Control register bits */
111/* Bit 7 Reserved */
112#define DS2781_CONTROL_NBEN (1 << 7)
113#define DS2781_CONTROL_UVEN (1 << 6)
114#define DS2781_CONTROL_PMOD (1 << 5)
115#define DS2781_CONTROL_RNAOP (1 << 4)
116#define DS1781_CONTROL_UVTH (1 << 3)
117/* Bit 0 - 2 Reserved */
118
119/* Special feature register bits */
120/* Bit 1 - 7 Reserved */
121#define DS2781_SFR_PIOSC (1 << 0)
122
123/* EEPROM register bits */
124#define DS2781_EEPROM_EEC (1 << 7)
125#define DS2781_EEPROM_LOCK (1 << 6)
126/* Bit 2 - 6 Reserved */
127#define DS2781_EEPROM_BL1 (1 << 1)
128#define DS2781_EEPROM_BL0 (1 << 0)
129
130extern int w1_ds2781_io(struct device *dev, char *buf, int addr, size_t count,
131 int io);
132extern int w1_ds2781_io_nolock(struct device *dev, char *buf, int addr,
133 size_t count, int io);
134extern int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd);
135
136#endif /* !_W1_DS2781_H */
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 490cda2281bc..874aeb05011b 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -38,6 +38,7 @@
38#define W1_EEPROM_DS2431 0x2D 38#define W1_EEPROM_DS2431 0x2D
39#define W1_FAMILY_DS2760 0x30 39#define W1_FAMILY_DS2760 0x30
40#define W1_FAMILY_DS2780 0x32 40#define W1_FAMILY_DS2780 0x32
41#define W1_FAMILY_DS2781 0x3D
41#define W1_THERM_DS28EA00 0x42 42#define W1_THERM_DS28EA00 0x42
42 43
43#define MAXNAMELEN 32 44#define MAXNAMELEN 32