2 * Copyright 2005, SDG Systems, LLC
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file COPYING in the main directory of this archive for
8 * Sat 11 Jun 2005 Aric D. Blumer
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/interrupt.h>
14 #include <linux/irq.h>
15 #include <linux/soc/asic3_base.h>
16 #include <linux/delay.h>
17 #include <linux/battery.h>
18 #include <linux/leds.h>
23 #include <asm/hardware/ipaq-asic3.h>
24 #include <asm/hardware/asic3_leds.h>
26 #include <asm/arch/hx4700-gpio.h>
27 #include <asm/arch/hx4700-asic.h>
28 #include <asm/arch/hx4700-core.h>
30 #define DRIVER_NAME "hx4700_power"
31 static char driver_name
[] = DRIVER_NAME
;
33 static void w1_init(void);
34 static void w1_deinit(void);
42 static int cdiv
= 0x2;
45 module_param(cdiv
, int, 0444);
46 MODULE_PARM_DESC(cdiv
, "Clock Divisor");
47 module_param(net
, int, 0444);
48 MODULE_PARM_DESC(net
, "Use net address");
51 volatile unsigned short __iomem
*base
;
53 wait_queue_head_t irqwait
;
54 unsigned short data_register
;
55 unsigned short irqstatus
;
57 struct timer_list irqtimer
;
78 #define DS1WM_COMMAND 0
81 #define DS1WM_IRQ_EN 3
82 #define DS1WM_CLOCK_DIV 4
84 #define WRITE_REGISTER(r, value) do { \
85 /* printk("Write %p = 0x%04x\n", (module_data.base + (r)), value); */ \
86 ((*(module_data.base + (r))) = (value)); \
89 #define READ_REGISTER(R, r) do { \
90 (R = *(module_data.base + (r))); \
91 /* printk("Read %p = 0x%04x\n", (module_data.base + (r)), R); */ \
94 static int w1_detect(void);
95 static int w1_write_byte(unsigned short data
);
96 static int w1_read_byte(unsigned int *data
);
97 static void w1_send_net_address(void);
99 DECLARE_MUTEX(update_mutex
);
102 update_data(int force
)
107 /* Only allow an update every second. */
108 if(!force
&& (module_data
.jiffies_64
+ 5 * HZ
> jiffies_64
)) {
112 if(down_trylock(&update_mutex
)) {
118 unsigned int readval
;
120 w1_send_net_address();
121 w1_write_byte(0x69); /* Read */
122 w1_write_byte(0x00); /* Starting at offset 0x0 */
123 w1_read_byte(&readval
); /* 0x0 */
124 if(readval
== 0xff) {
126 * We have an unknown read problem. Try again.
130 // printk("hx4700_power: Whoops\n");
136 /* Get rid of stuff we don't want */
137 w1_read_byte(&readval
); /* 0x1 */
138 w1_read_byte(&readval
); /* 0x2 */
139 w1_read_byte(&readval
); /* 0x3 */
140 w1_read_byte(&readval
); /* 0x4 */
141 w1_read_byte(&readval
); /* 0x5 */
142 w1_read_byte(&readval
); /* 0x6 */
143 w1_read_byte(&readval
); /* 0x7 */
144 w1_read_byte(&readval
); /* 0x8 */
145 w1_read_byte(&readval
); /* 0x9 */
146 w1_read_byte(&readval
); /* 0xa */
147 w1_read_byte(&readval
); /* 0xb */
150 w1_read_byte(&readval
); /* 0xc */
151 if(readval
== 0xff) {
153 * We have an unknown read problem. Try again.
157 // printk("hx4700_power: Whoops2\n");
162 module_data
.voltage
= readval
<< 8;
163 w1_read_byte(&readval
); /* 0xd */
164 if(readval
== 0xff) {
166 * We have an unknown read problem. Try again.
170 // printk("hx4700_power: Whoops2\n");
175 module_data
.voltage
|= readval
;
176 module_data
.voltage
>>= 5;
177 /* 4997 / 1024 is almost equal to 4880 / 1000 */
178 module_data
.voltage
*= 4997;
179 module_data
.voltage
/= 1024;
183 w1_read_byte(&readval
); /* 0xe */
184 if(readval
== 0xff) {
186 * We have an unknown read problem. Try again.
190 // printk("hx4700_power: Whoops2\n");
195 if(readval
& (1 << 7)) {
196 /* The sign bit is set */
197 module_data
.Current
= -1 ^ 0x7fff;
199 module_data
.Current
= 0;
201 module_data
.Current
|= readval
<< 8;
202 w1_read_byte(&readval
); /* 0xf */
203 if(readval
== 0xff) {
205 * We have an unknown read problem. Try again.
209 // printk("hx4700_power: Whoops2\n");
214 module_data
.Current
|= readval
;
215 module_data
.Current
>>= 3;
216 /* 655360 / 1024*1024 is equal to 6250000 / 1000000 */
217 module_data
.Current
*= 655360;
218 module_data
.Current
/= 1024 * 1024;
221 /* Current Accumulator */
222 w1_read_byte(&readval
); /* 0x10 */
223 if(readval
== 0xff) {
225 * We have an unknown read problem. Try again.
229 // printk("hx4700_power: Whoops2\n");
234 if(readval
& (1 << 7)) {
235 /* The sign bit is set */
236 module_data
.current_accum
= -1 ^ 0xffff;
238 module_data
.current_accum
= 0;
240 module_data
.current_accum
|= readval
<< 8;
241 w1_read_byte(&readval
); /* 0x11 */
242 if(readval
== 0xff) {
244 * We have an unknown read problem. Try again.
248 // printk("hx4700_power: Whoops2\n");
253 module_data
.current_accum
|= readval
;
254 /* Units are 250 uAh. We wan't mAh. So each unit is 1/4 mAh. But
255 * we want fractions of hours, so let's keep the 1/4 mAh units. */
256 /* Now convert to quarter hours by dividing by mA. */
257 if(module_data
.Current
== 0) {
258 module_data
.minutes
= module_data
.current_accum
* 15;
260 module_data
.minutes
= -((module_data
.current_accum
* 15) / module_data
.Current
);
264 /* Get rid of stuff we don't want */
265 w1_read_byte(&readval
); /* 0x12 */
266 w1_read_byte(&readval
); /* 0x13 */
267 w1_read_byte(&readval
); /* 0x14 */
268 w1_read_byte(&readval
); /* 0x15 */
269 w1_read_byte(&readval
); /* 0x16 */
270 w1_read_byte(&readval
); /* 0x17 */
273 w1_read_byte(&readval
); /* 0x18 */
274 if(readval
== 0xff) {
276 * We have an unknown read problem. Try again.
280 // printk("hx4700_power: Whoops2\n");
285 module_data
.temp
= readval
<< 8;
286 w1_read_byte(&readval
); /* 0x19 */
287 if(readval
== 0xff) {
289 * We have an unknown read problem. Try again.
293 // printk("hx4700_power: Whoops2\n");
298 module_data
.temp
|= readval
;
299 module_data
.temp
>>= 5;
300 module_data
.temp
+= module_data
.temp
/ 4;
303 if(module_data
.voltage
> 8000) {
304 /* There is an unknown problem where things get into a strange
305 * state. We know it because the voltage is reported as too
306 * high. This is an attempt at robustness to correct the problem.
307 * I'd like to fix it permanently, though.
310 printk("%s: Bad state detected. Retrying.\n", driver_name
);
315 printk("w1 fix didn't work. We give up.\n");
319 /* Reset ACR when battery gets full. */
320 if (module_data
.Current
>= 0 && module_data
.Current
< 32 &&
321 !module_data
.acr_reset
) {
322 printk(KERN_INFO
"ACR reset\n");
323 module_data
.current_accum
= 1800 * 4;
325 w1_send_net_address();
326 w1_write_byte(0x6c); /* write */
327 w1_write_byte(0x10); /* current accum msb */
328 w1_write_byte((module_data
.current_accum
>> 8) & 0xff);
329 w1_write_byte(module_data
.current_accum
& 0xff);
330 module_data
.acr_reset
= 1;
334 module_data
.battery_life
= (module_data
.current_accum
* 25) / 1800;
335 if(module_data
.battery_life
> 100) module_data
.battery_life
= 100;
336 if(module_data
.battery_life
< 0) module_data
.battery_life
= 0;
338 printk("%s: Device not detected\n", driver_name
);
339 module_data
.temp
= 0;
340 module_data
.voltage
= 0;
341 module_data
.current_accum
= 0;
342 module_data
.Current
= 0;
346 module_data
.jiffies_64
= jiffies_64
;
352 w1_isr(int irq
, void *opaque
)
355 * Note that the w1 control logic is quite slow, running at 1 MHz. It is
356 * possible to read the IRQ status, and return and the interrupt still be
357 * active. In this case, we're OK because we only update the irqstatus
358 * when an actual interrupt causing bit is set.
362 /* Just reading the register clears the source */
363 READ_REGISTER(tmp
, DS1WM_IRQ
);
364 if( tmp
& (1 << 0) /* Presence Detect */
365 || tmp
& (1 << 4) /* Receive Buffer Full */
368 module_data
.irqstatus
= tmp
;
369 for(count
= 0; count
< 10; count
++) {
370 READ_REGISTER(module_data
.data_register
, DS1WM_TXRX
);
371 READ_REGISTER(junk
, DS1WM_CLOCK_DIV
); /* Delay */
372 READ_REGISTER(tmp
, DS1WM_IRQ
);
373 if(!(tmp
& (1 << 4))) break;
375 wake_up_interruptible(&module_data
.irqwait
);
384 /* Turn on external clocks and the OWM clock */
385 asic3_set_clock_cdex(&hx4700_asic3
.dev
,
386 CLOCK_CDEX_EX0
| CLOCK_CDEX_EX1
| CLOCK_CDEX_OWM
,
387 CLOCK_CDEX_EX0
| CLOCK_CDEX_EX1
| CLOCK_CDEX_OWM
);
391 asic3_set_extcf_reset(&hx4700_asic3
.dev
, ASIC3_EXTCF_OWM_RESET
, ASIC3_EXTCF_OWM_RESET
);
393 asic3_set_extcf_reset(&hx4700_asic3
.dev
, ASIC3_EXTCF_OWM_RESET
, 0);
396 /* Clear OWM_SMB, set OWM_EN */
397 asic3_set_extcf_select(&hx4700_asic3
.dev
,
398 ASIC3_EXTCF_OWM_SMB
| ASIC3_EXTCF_OWM_EN
,
399 0 | ASIC3_EXTCF_OWM_EN
);
403 WRITE_REGISTER(DS1WM_CLOCK_DIV
, cdiv
);
404 /* Enable interrupts: RBF, PD */
405 /* Set Interrupt Active High (IAS = 1) */
406 WRITE_REGISTER(DS1WM_IRQ_EN
,
408 | (0 << 5) /* ESINT */
409 | (1 << 4) /* ERBF */
410 | (0 << 3) /* ETMT */
411 | (0 << 2) /* ETBE */
412 | (1 << 1) /* IAS 0 = active low interrupt, 1 = active high */
418 /* Set asic3 interrupt status to zero. Hmmmmm. not accesible in
428 module_data
.irqstatus
= 0;
430 /* Set 1WR (one wire reset) bit */
431 WRITE_REGISTER(DS1WM_COMMAND
, 1);
432 if(wait_event_interruptible_timeout(module_data
.irqwait
,
433 module_data
.irqstatus
& (1 << 0) /* PD set? */, HZ
)) {
435 if(0 == (module_data
.irqstatus
& (1 << 1)) /* PDR set? */) {
440 printk("%s: detect timeout\n", driver_name
);
450 w1_read_byte(unsigned int *data
)
452 module_data
.irqstatus
= 0;
453 WRITE_REGISTER(DS1WM_TXRX
, 0xff);
454 if(wait_event_interruptible_timeout(module_data
.irqwait
,
455 module_data
.irqstatus
& (1 << 4) /* RBF set? */, HZ
)) {
456 *data
= module_data
.data_register
;
459 printk("%s: RBF not set\n", driver_name
);
465 w1_write_byte(unsigned short data
)
467 module_data
.irqstatus
= 0;
468 WRITE_REGISTER(DS1WM_TXRX
, data
);
469 if(wait_event_interruptible_timeout(module_data
.irqwait
,
470 module_data
.irqstatus
& (1 << 2) /* TBE set? */, HZ
)) {
473 printk("%s: TBE not set\n", driver_name
);
478 int get_min_voltage(struct battery
*b
)
482 int get_min_current(struct battery
*b
)
484 return -1900; /* negative 1900 mA */
486 int get_min_charge(struct battery
*b
)
490 int get_max_voltage(struct battery
*b
)
492 return 4750; /* mV */
494 int get_max_current(struct battery
*b
)
496 return 1900; /* positive 1900 mA */
498 int get_max_charge(struct battery
*b
)
502 int get_temp(struct battery
*b
)
505 return module_data
.temp
;
507 int get_voltage(struct battery
*b
)
510 return module_data
.voltage
;
512 int get_Current(struct battery
*b
)
515 return module_data
.Current
;
517 int get_charge(struct battery
*b
)
519 return module_data
.current_accum
/ 4;
521 int get_status(struct battery
*b
)
523 return power_status
== POWER_NONE
? 0: 1;
526 static struct battery hx4700_power
= {
527 .name
= "hx4700_primary",
529 .get_min_voltage
= get_min_voltage
,
530 .get_min_current
= get_min_current
,
531 .get_min_charge
= get_min_charge
,
532 .get_max_voltage
= get_max_voltage
,
533 .get_max_current
= get_max_current
,
534 .get_max_charge
= get_max_charge
,
535 .get_temp
= get_temp
,
536 .get_voltage
= get_voltage
,
537 .get_current
= get_Current
,
538 .get_charge
= get_charge
,
539 .get_status
= get_status
,
542 DEFINE_LED_TRIGGER(charging_trig
);
543 DEFINE_LED_TRIGGER(chargefull_trig
);
546 set_leds(int status
, int Current
, int battery_life
)
548 if (status
== APM_AC_ONLINE
) {
549 /* check life to update LEDs. LEDs are off when on battery */
551 * It has been observed that the Current is greater when the device is
552 * suspended compared to when it is awake. So we have to use
553 * different parameters here compared to bootldr
555 if((Current
< 32) && (battery_life
== 100)) {
556 /* Green LED on solid, amber off */
557 led_trigger_event(chargefull_trig
, LED_FULL
);
558 led_trigger_event(charging_trig
, LED_OFF
);
560 /* Amber LED blinking, green off */
561 led_trigger_event(chargefull_trig
, LED_OFF
);
562 led_trigger_event(charging_trig
, LED_FULL
);
565 /* No charging power is applied; both LEDs off */
566 led_trigger_event(chargefull_trig
, LED_OFF
);
567 led_trigger_event(charging_trig
, LED_OFF
);
573 hx4700_apm_get_power_status( struct apm_power_info
*info
)
577 info
->ac_line_status
= (power_status
== POWER_NONE
)
578 ? APM_AC_OFFLINE
: APM_AC_ONLINE
;
580 /* It is possible to be hooked up to USB and getting some power from
581 * it, but still having a current drain on the battery with a busy CPU
583 info
->battery_life
= module_data
.battery_life
;
585 if (info
->ac_line_status
== APM_AC_ONLINE
) {
586 info
->battery_status
= APM_BATTERY_STATUS_CHARGING
;
588 info
->time
= module_data
.minutes
;
589 info
->units
= APM_UNITS_MINS
;
590 module_data
.acr_reset
= 0;
592 info
->battery_status
= APM_BATTERY_STATUS_CRITICAL
;
593 if(info
->battery_life
> 5) {
594 info
->battery_status
= APM_BATTERY_STATUS_LOW
;
596 if(info
->battery_life
> 20) {
597 info
->battery_status
= APM_BATTERY_STATUS_HIGH
;
601 set_leds(info
->ac_line_status
, module_data
.Current
, module_data
.battery_life
);
605 power_change_task_handler(unsigned long enableirq
)
610 if(!module_data
.initialized
) return;
612 retval
= asic3_get_gpio_status_d( &hx4700_asic3
.dev
);
613 ac_in
= (retval
& (1<<GPIOD_AC_IN_N
)) == 0;
614 usb_in
= (retval
& (1<<GPIOD_USBC_DETECT_N
)) == 0;
615 printk( KERN_INFO
"hx4700 power_change: ac_in=%d\n", ac_in
);
616 printk( KERN_INFO
"hx4700 power_change: usb_in=%d\n", usb_in
);
619 set_irq_type( module_data
.usb_irq
, IRQT_RISING
);
621 set_irq_type( module_data
.usb_irq
, IRQT_FALLING
);
625 set_irq_type( module_data
.ac_irq
, IRQT_RISING
);
627 set_irq_type( module_data
.ac_irq
, IRQT_FALLING
);
631 /* If we're on AC, it doesn't matter if we're on USB or not, use AC
633 SET_HX4700_GPIO_N( CHARGE_EN
, 1 );
634 SET_HX4700_GPIO( USB_CHARGE_RATE
, 0 );
635 power_status
= POWER_AC
;
636 set_leds(APM_AC_ONLINE
, module_data
.Current
, module_data
.battery_life
);
638 /* We're not on AC, but we are on USB, so charge with that */
639 SET_HX4700_GPIO( USB_CHARGE_RATE
, 1 );
640 SET_HX4700_GPIO_N( CHARGE_EN
, 1 );
641 power_status
= POWER_USB
;
642 set_leds(APM_AC_ONLINE
, module_data
.Current
, module_data
.battery_life
);
644 /* We're not on AC or USB, don't charge */
645 SET_HX4700_GPIO_N( CHARGE_EN
, 0 );
646 SET_HX4700_GPIO( USB_CHARGE_RATE
, 0 );
647 power_status
= POWER_NONE
;
648 set_leds(APM_AC_OFFLINE
, module_data
.Current
, module_data
.battery_life
);
649 module_data
.acr_reset
= 0;
653 /* update_data(1); */
654 module_data
.jiffies_64
= 0; /* Force a re-read on next try */
657 enable_irq(module_data
.usb_irq
);
658 enable_irq(module_data
.ac_irq
);
663 attach_isr(int irq
, void *dev_id
)
665 if(irq
!= module_data
.usb_irq
666 && irq
!= module_data
.ac_irq
) {
667 printk("Bad irq: %d, not %d or %d\n", irq
, module_data
.usb_irq
, module_data
.ac_irq
);
669 if(module_data
.initialized
) {
670 SET_HX4700_GPIO_N( CHARGE_EN
, 0 );
671 mod_timer(&module_data
.irqtimer
, jiffies
+ HZ
/10);
672 disable_irq(module_data
.usb_irq
);
673 disable_irq(module_data
.ac_irq
);
679 battery_class_uevent(struct class_device
*dev
, char **envp
, int num_envp
,
680 char *buffer
, int buffer_size
)
686 battery_class_release(struct class_device
*dev
)
691 battery_class_class_release(struct class *class)
696 w1_send_net_address(void)
700 w1_write_byte(0x55); /* Match Net Address */
701 for(i
= 0; i
< sizeof(module_data
.net_address
)/sizeof(module_data
.net_address
[0]); i
++) {
702 w1_write_byte(module_data
.net_address
[i
]);
705 w1_write_byte(0xcc); /* Skip Net Address */
710 w1_probe(struct platform_device
*pdev
)
714 led_trigger_register_simple("hx4700-chargefull", &chargefull_trig
);
715 led_trigger_register_asic3_timer("hx4700-charging", &charging_trig
);
716 led_trigger_event(chargefull_trig
, LED_OFF
);
717 led_trigger_event(charging_trig
, LED_OFF
);
719 module_data
.initialized
= 0;
720 module_data
.w1_irq
= -1;
721 module_data
.usb_irq
= -1;
722 module_data
.ac_irq
= -1;
723 module_data
.base
= 0;
724 module_data
.jiffies_64
= 0;
725 module_data
.acr_reset
= 0;
727 init_timer(&module_data
.irqtimer
);
728 module_data
.irqtimer
.function
= power_change_task_handler
;
729 module_data
.irqtimer
.data
= 1;
731 init_waitqueue_head(&module_data
.irqwait
);
733 platform_set_drvdata(pdev
, &module_data
);
735 module_data
.base
= ioremap_nocache(0x0c000600, 64);
736 module_data
.battery_class
= 0;
738 if(!module_data
.base
) {
739 printk(KERN_NOTICE
"%s: Unable to map device\n", driver_name
);
744 module_data
.w1_irq
= asic3_irq_base(&hx4700_asic3
.dev
) + ASIC3_OWM_IRQ
;
745 retval
= request_irq(module_data
.w1_irq
, w1_isr
, SA_INTERRUPT
, driver_name
, &module_data
);
747 printk(KERN_NOTICE
"%s: Unable to get interrupt %d: %d\n",
748 driver_name
, module_data
.w1_irq
, retval
);
749 iounmap((void __iomem
*)module_data
.base
);
750 module_data
.base
= 0;
751 module_data
.w1_irq
= -1;
757 unsigned int readval
;
760 for(i
= 0; i
< sizeof(module_data
.net_address
)/sizeof(module_data
.net_address
[0]); i
++) {
761 w1_read_byte(&readval
);
762 module_data
.net_address
[i
] = readval
& 0xff;
764 if(module_data
.net_address
[0] != 0x30) {
765 printk("Looks like wrong net address is "
766 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
767 module_data
.net_address
[0], module_data
.net_address
[1],
768 module_data
.net_address
[2], module_data
.net_address
[3],
769 module_data
.net_address
[4], module_data
.net_address
[5],
770 module_data
.net_address
[6], module_data
.net_address
[7]
774 printk("Could not detect device for net address\n");
775 iounmap((void __iomem
*)module_data
.base
);
776 free_irq(module_data
.w1_irq
, &module_data
);
777 module_data
.base
= 0;
778 module_data
.w1_irq
= -1;
782 unsigned int readval
;
783 if(battery_class_register(&hx4700_power
)) {
784 printk(KERN_ERR
"%s: Could not register battery class\n",
787 module_data
.battery_class
= 1;
788 hx4700_power
.class_dev
.class->uevent
= battery_class_uevent
;
789 hx4700_power
.class_dev
.class->release
= battery_class_release
;
790 hx4700_power
.class_dev
.class->class_release
= battery_class_class_release
;
792 w1_send_net_address();
793 w1_write_byte(0x69); /* Read */
794 w1_write_byte(0x08); /* Special Feature Address */
795 w1_read_byte(&readval
);
796 if(!(readval
& (1 << 7))) {
797 printk("PS is low. Writing 1.\n");
798 /* The PS signal is low. The docs say to write a 1 to it to ensure
799 * proper operation. */
801 w1_send_net_address();
802 w1_write_byte(0x6c); /* Write */
803 w1_write_byte(0x08); /* Special Feature Address */
804 w1_write_byte(readval
| (1 << 7)); /* Data */
806 printk("No detect when writing PS\n");
810 printk("%s: Device not detected on init\n", driver_name
);
814 module_data
.usb_irq
= asic3_irq_base( &hx4700_asic3
.dev
) + ASIC3_GPIOD_IRQ_BASE
815 + GPIOD_USBC_DETECT_N
;
816 module_data
.ac_irq
= asic3_irq_base( &hx4700_asic3
.dev
) + ASIC3_GPIOD_IRQ_BASE
818 module_data
.initialized
= 1;
820 /* Get first power state */
821 power_change_task_handler(0);
824 if (request_irq( module_data
.usb_irq
, attach_isr
, SA_INTERRUPT
,
825 "Hx4700 USB Detect", NULL
) != 0) {
826 printk( KERN_ERR
"Unable to configure USB detect interrupt.\n" );
827 module_data
.usb_irq
= -1;
831 if (request_irq( module_data
.ac_irq
, attach_isr
, SA_INTERRUPT
,
832 "Hx4700 AC Detect", NULL
) != 0) {
833 printk( KERN_ERR
"Unable to configure AC detect interrupt.\n" );
834 module_data
.ac_irq
= -1;
838 apm_get_power_status
= hx4700_apm_get_power_status
;
847 /* Turn off OWM clock. I hate to touch the others because they might be
848 * used by other devices like MMC. */
849 asic3_set_clock_cdex(&hx4700_asic3
.dev
,
850 /* CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | */ CLOCK_CDEX_OWM
,
851 /* CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | */ 0);
854 asic3_set_extcf_select(&hx4700_asic3
.dev
,
855 ASIC3_EXTCF_OWM_EN
, 0);
861 w1_remove(struct platform_device
*pdev
)
863 printk("w1_remove\n");
865 led_trigger_unregister_simple(chargefull_trig
);
866 led_trigger_unregister_asic3_timer(charging_trig
);
869 apm_get_power_status
= NULL
;
872 if(module_data
.base
) {
875 if(module_data
.battery_class
) {
876 battery_class_unregister(&hx4700_power
);
877 printk("battery class unregistered\n");
879 if(module_data
.base
) {
880 iounmap((void __iomem
*)module_data
.base
);
881 printk("Base unmapped\n");
883 if(module_data
.w1_irq
!= -1) {
884 disable_irq(module_data
.w1_irq
);
885 free_irq(module_data
.w1_irq
, &module_data
);
886 printk("w1 irq freed\n");
888 if (module_data
.ac_irq
!= -1) {
889 disable_irq(module_data
.ac_irq
);
890 free_irq( module_data
.ac_irq
, NULL
);
891 printk("ac irq freed\n");
893 if (module_data
.usb_irq
!= -1) {
894 disable_irq(module_data
.usb_irq
);
895 free_irq( module_data
.usb_irq
, NULL
);
896 printk("usb irq freed\n");
899 while(timer_pending(&module_data
.irqtimer
)) {
902 del_timer(&module_data
.irqtimer
);
908 w1_suspend(struct platform_device
*pdev
, pm_message_t state
)
910 // printk("w1_suspend\n");
916 w1_resume(struct platform_device
*pdev
)
918 // printk("w1_resume\n");
920 /* check for changes to power that may have occurred */
921 power_change_task_handler(0);
922 /* I think this will work to ensure the interrupt is unmasked. */
923 disable_irq(module_data
.w1_irq
);
924 enable_irq(module_data
.w1_irq
);
925 /* Clear OWM_SMB, set OWM_EN */
926 asic3_set_extcf_select(&hx4700_asic3
.dev
, ASIC3_EXTCF_OWM_EN
, ASIC3_EXTCF_OWM_EN
);
930 static struct platform_driver w1_driver
= {
932 .name
= "hx4700-power",
936 .suspend
= w1_suspend
,
943 printk(KERN_NOTICE
"hx4700 Power Management Driver\n");
944 return platform_driver_register(&w1_driver
);
950 platform_driver_unregister(&w1_driver
);
956 MODULE_AUTHOR("Aric D. Blumer, SDG Systems, LLC");
957 MODULE_DESCRIPTION("hx4700 Power Management Driver");
958 MODULE_LICENSE("GPL");
960 /* vim600: set expandtab: */