2 * Copyright (C) 2012 Spreadtrum Communications Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 #ifdef SPRDBAT_TWO_CHARGE_CHANNEL
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/err.h>
18 #include <linux/platform_device.h>
19 #include <linux/power_supply.h>
20 #include <linux/types.h>
21 #include <linux/pci.h>
22 #include <linux/interrupt.h>
24 #include <linux/hrtimer.h>
25 #include <linux/spinlock.h>
26 #include <linux/gpio.h>
27 #include <linux/irq.h>
28 #include <linux/wakelock.h>
29 #include <linux/delay.h>
30 #include <mach/hardware.h>
33 #include <mach/gpio.h>
34 #include <linux/device.h>
36 #include <linux/slab.h>
37 #include <linux/jiffies.h>
38 #include "sprd_battery.h"
41 struct sprdchg_drivier_data_ext {
42 uint32_t gpio_vchg_ovi;
43 uint32_t irq_vchg_ovi;
44 uint32_t gpio_charge_en;
45 uint32_t gpio_charge_done;
46 struct work_struct ovi_irq_work;
48 static struct sprdchg_drivier_data_ext sprdchg_ext_ic;
50 int sprdchg_is_chg_done_ext(void)
52 return gpio_get_value(sprdchg_ext_ic.gpio_charge_done);
55 void sprdchg_start_charge_ext(void)
57 gpio_set_value(sprdchg_ext_ic.gpio_charge_en, 0);
60 void sprdchg_stop_charge_ext(void)
62 gpio_set_value(sprdchg_ext_ic.gpio_charge_en, 1);
65 void sprdchg_open_ovi_fun_ext(void)
67 irq_set_irq_type(sprdchg_ext_ic.irq_vchg_ovi, IRQ_TYPE_LEVEL_HIGH);
68 enable_irq(sprdchg_ext_ic.irq_vchg_ovi);
71 void sprdchg_close_ovi_fun_ext(void)
73 disable_irq_nosync(sprdchg_ext_ic.irq_vchg_ovi);
76 static void sprdchg_ovi_irq_works_ext(struct work_struct *work)
79 value = gpio_get_value(sprdchg_ext_ic.gpio_vchg_ovi);
81 sprdbat_charge_event_ext(SPRDBAT_CHG_EVENT_EXT_OVI);
83 sprdbat_charge_event_ext(SPRDBAT_CHG_EVENT_EXT_OVI_RESTART);
87 static __used irqreturn_t sprdchg_vchg_ovi_irq_ext(int irq, void *dev_id)
90 value = gpio_get_value(sprdchg_ext_ic.gpio_vchg_ovi);
92 printk("sprdchg_vchg_ovi_irq_ext ovi high\n");
93 irq_set_irq_type(sprdchg_ext_ic.irq_vchg_ovi, IRQ_TYPE_LEVEL_LOW);
95 printk("sprdchg_vchg_ovi_irq_ext ovi low\n");
96 irq_set_irq_type(sprdchg_ext_ic.irq_vchg_ovi, IRQ_TYPE_LEVEL_HIGH);
98 schedule_work(&sprdchg_ext_ic.ovi_irq_work);
102 int sprdchg_charge_init_ext(struct platform_device *pdev)
105 struct resource *res = NULL;
107 res = platform_get_resource(pdev, IORESOURCE_IO, 3);
108 sprdchg_ext_ic.gpio_charge_done = res->start;
109 res = platform_get_resource(pdev, IORESOURCE_IO, 4);
110 sprdchg_ext_ic.gpio_charge_en = res->start;
111 res = platform_get_resource(pdev, IORESOURCE_IO, 5);
112 sprdchg_ext_ic.gpio_vchg_ovi = res->start;
113 gpio_request(sprdchg_ext_ic.gpio_vchg_ovi, "vchg_ovi_ext");
114 gpio_direction_input(sprdchg_ext_ic.gpio_vchg_ovi);
115 sprdchg_ext_ic.irq_vchg_ovi = gpio_to_irq(sprdchg_ext_ic.gpio_vchg_ovi);
116 set_irq_flags(sprdchg_ext_ic.irq_vchg_ovi, IRQF_VALID | IRQF_NOAUTOEN);
117 ret = request_irq(sprdchg_ext_ic.irq_vchg_ovi, sprdchg_vchg_ovi_irq_ext,
118 IRQF_NO_SUSPEND, "sprdbat_vchg_ovi_ext", NULL);
119 INIT_WORK(&sprdchg_ext_ic.ovi_irq_work, sprdchg_ovi_irq_works_ext);
120 gpio_request(sprdchg_ext_ic.gpio_charge_done, "chg_done_ext");
121 gpio_direction_input(sprdchg_ext_ic.gpio_charge_done);
122 gpio_request(sprdchg_ext_ic.gpio_charge_en, "charge_en_ext");
123 gpio_direction_output(sprdchg_ext_ic.gpio_charge_en, 1);
124 sprdchg_stop_charge_ext();
128 void sprdchg_chg_monitor_cb_ext(void *data)