2 * linux/arch/arm/mach-s5pv310/charger-c1.c
4 * MyungJoo Ham <myungjoo.ham@samsung.com>
6 * C1(NURI) Board Charger Support with Charger-Manager Framework
12 #include <linux/err.h>
13 #include <linux/platform_device.h>
14 #include <linux/ntc.h>
15 #include <linux/rtc/rtc-s3c.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/power/charger-manager.h>
18 #include <linux/power/max17042_battery.h>
19 #include <linux/mfd/max8997.h>
24 #include <mach/regs-pmu.h>
25 #include <mach/irqs.h>
27 #include "../../../fs/sysfs/sysfs.h"
29 /* Temperatures in milli-centigrade */
30 #define SECBATTSPEC_TEMP_HIGH (63 * 1000)
31 #define SECBATTSPEC_TEMP_HIGH_REC (58 * 1000)
32 #define SECBATTSPEC_TEMP_LOW (-5 * 1000)
33 #define SECBATTSPEC_TEMP_LOW_REC (0 * 1000)
35 #ifdef CONFIG_SENSORS_NTC_THERMISTOR
36 static unsigned int read_thermistor_uV(void)
38 struct s3c_adc_request req = {
42 .channel = 6, /* XADCAIN_6 */
45 return s3c_adc_convert_uV(s3c_adc_get(&req));
48 static struct ntc_thermistor_platform_data ncp15wb473_pdata = {
49 .read_uV = read_thermistor_uV,
50 .pullup_uV = 3300000, /* VADC_3.3V_C210 */
51 .pullup_ohm = 100000, /* R613 in SLP 7 0105 */
52 .pulldown_ohm = 100000, /* R615 in SLP 7 0105 */
53 .connect = NTC_CONNECTED_GROUND,
56 struct platform_device c1_ncp15wb473_thermistor;
57 static const char *thermistor_dirent = "temp1_input";
58 static struct device_attribute *thermistor_attr;
59 static int __read_thermistor_mC(void)
66 if (thermistor_attr == NULL) {
68 struct sysfs_dirent *ntc_d;
70 ntc = &c1_ncp15wb473_thermistor.dev.kobj;
71 ntc_d = sysfs_get_dirent(ntc->sd,
72 get_ktype(ntc)->namespace(ntc),
74 if (!ntc_d || sysfs_type(ntc_d) != SYSFS_KOBJ_ATTR) {
76 dev_err(&c1_ncp15wb473_thermistor.dev, "Cannot init"
77 "ialize ncp15wb473's dirent info.\n");
82 thermistor_attr = container_of(ntc_d->s_attr.attr,
83 struct device_attribute, attr);
88 if (IS_ERR(thermistor_attr)) {
89 dev_warn(&c1_ncp15wb473_thermistor.dev, "Cannot read.\n");
93 count = thermistor_attr->show(&c1_ncp15wb473_thermistor.dev,
94 thermistor_attr, buf);
96 sscanf(buf, "%d", &mC);
100 thermistor_attr = ERR_PTR(err);
104 #else /* CONFIG_SENSORS_NTC_THERMISTOR */
105 static int __read_thermistor_mC(void)
107 return 25000; /* 25 mili-Centigrade */
109 #endif /* CONFIG_SENSORS_NTC_THERMISTOR */
111 static bool s3c_wksrc_rtc_alarm(void)
113 u32 reg = s3c_suspend_wakeup_stat & S5P_WAKEUP_STAT_WKSRC_MASK;
115 if ((reg & S5P_WAKEUP_STAT_RTCALARM) &&
116 !(reg & ~S5P_WAKEUP_STAT_RTCALARM))
117 return true; /* yes, it is */
122 enum temp_stat { TEMP_OK = 0, TEMP_HOT = 1, TEMP_COLD = -1 };
124 static int c1_thermistor_ck(int *mC)
126 static enum temp_stat state = TEMP_OK;
128 *mC = __read_thermistor_mC();
131 if (*mC >= SECBATTSPEC_TEMP_HIGH)
133 else if (*mC <= SECBATTSPEC_TEMP_LOW)
137 if (*mC <= SECBATTSPEC_TEMP_LOW)
139 else if (*mC < SECBATTSPEC_TEMP_HIGH_REC)
143 if (*mC >= SECBATTSPEC_TEMP_HIGH)
145 else if (*mC > SECBATTSPEC_TEMP_LOW_REC)
148 pr_err("%s has invalid state %d\n", __func__, state);
154 static char *c1_charger_stats[] = { "max8997_pmic", NULL };
155 static struct regulator_bulk_data c1_chargers[] = {
156 { .supply = "vinchg1", },
158 static struct charger_irq c1_chg_irqs[] = {
159 { IRQ_PMIC_BASE + MAX8997_PMICIRQ_TOPOFFR, 0, CM_IRQ_BATT_FULL,
161 { IRQ_FUEL_BASE + MAX17042_IRQ_Battery_Removed, 0, CM_IRQ_BATT_OUT,
163 { IRQ_PMIC_BASE + MAX8997_PMICIRQ_CHGRSTF, 0, CM_IRQ_CHG_START_STOP,
165 { IRQ_PMIC_BASE + MAX8997_PMICIRQ_MBCHGTMEXPD, 0, CM_IRQ_OTHERS,
166 true, "CHG TIMEOUT" },
167 { IRQ_PMIC_BASE + MAX8997_PMICIRQ_DCINOVP, 0, CM_IRQ_OTHERS,
168 true, "CHG OVERVOLT" },
169 { IRQ_PMIC_BASE + MAX8997_PMICIRQ_CHGINS, 0, CM_IRQ_EXT_PWR_IN_OUT,
170 true, "CHG PWR Insert" },
171 { IRQ_PMIC_BASE + MAX8997_PMICIRQ_CHGRM, 0, CM_IRQ_EXT_PWR_IN_OUT,
172 true, "CHG PWR Remove" },
173 { 0, 0, 0, false, NULL },
176 static struct charger_desc c1_charger_desc = {
177 .psy_name = "battery",
178 .polling_interval_ms = 30000,
179 .polling_mode = CM_POLL_CHARGING_ONLY,
180 .fullbatt_vchkdrop_ms = 30000,
181 .fullbatt_vchkdrop_uV = 100000,
182 .fullbatt_uV = 4200000,
183 .battery_present = CM_FUEL_GAUGE,
184 .psy_charger_stat = c1_charger_stats,
185 .charger_regulators = c1_chargers,
186 .num_charger_regulators = ARRAY_SIZE(c1_chargers),
187 .psy_fuel_gauge = "max17042_battery",
190 .is_temperature_error = c1_thermistor_ck,
191 .measure_ambient_temp = true,
192 .measure_battery_temp = false,
195 struct charger_global_desc c1_charger_g_desc = {
197 .is_rtc_only_wakeup_reason = s3c_wksrc_rtc_alarm,
198 .assume_timer_stops_in_suspend = true,
201 #ifdef CONFIG_SENSORS_NTC_THERMISTOR
202 struct platform_device c1_ncp15wb473_thermistor = {
203 .name = "ncp15wb473",
205 .platform_data = &ncp15wb473_pdata,
210 struct platform_device c1_charger_manager = {
211 .name = "charger-manager",
213 .platform_data = &c1_charger_desc,