2 * drivers/mfd/rt5036-misc.c
3 * Driver for Richtek RT5036 PMIC misc option
5 * Copyright (C) 2014 Richtek Technology Corp.
6 * cy_huang <cy_huang@richtek.com>
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; either version 2
11 * of the License, or (at your option) any later version.
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/err.h>
18 #include <linux/platform_device.h>
19 #include <linux/i2c.h>
21 #include <linux/power_supply.h>
22 #ifdef CONFIG_MISC_RT5036_PWRKEY
23 #include <linux/input.h>
24 #endif /* #ifdef CONFIG_MISC_RT5036_PWRKEY */
26 #include <linux/mfd/rt5036/rt5036.h>
27 #include <linux/mfd/rt5036/rt5036-misc.h>
29 static struct i2c_client *g_shdn;
31 static unsigned char misc_init_regval[] = {
40 #ifdef CONFIG_MISC_RT5036_PWRKEY
44 #endif /* #ifdef CONFIG_RT5036_PWRKEY */
47 int rt5036_vin_exist(void)
50 #ifdef CONFIG_CHARGER_RT5036
51 union power_supply_propval pval;
52 struct power_supply *psy = power_supply_get_by_name("rt-charger");
55 ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &pval);
61 pr_err("couldn't get rt-charger psy\n");
66 ret = rt5036_reg_read(g_shdn, RT5036_REG_CHGSTAT2);
67 return ret < 0 ? 0 : ret & RT5036_PWRRDY_MASK;
68 #endif /* #ifdef CONFIG_CHARGER_RT5036 */
70 EXPORT_SYMBOL(rt5036_vin_exist);
71 static bool rt_pm_off;
72 void rt5036_chip_shutdown(void)
75 rt5036_set_bits(g_shdn, RT5036_REG_MISC3, RT5036_CHIPSHDN_MASK);
76 rt5036_clr_bits(g_shdn, RT5036_REG_MISC3, RT5036_CHIPSHDN_MASK);
79 EXPORT_SYMBOL(rt5036_chip_shutdown);
81 static void rt5036_general_irq_handler(void *info, int eventno)
83 struct rt5036_misc_info *mi = info;
85 dev_info(mi->dev, "eventno=%02d\n", eventno);
86 #ifdef CONFIG_MISC_RT5036_PWRKEY
88 case MISCEVENT_PWRONF:
89 if (!mi->pwr_key_pressed) {
90 input_report_key(mi->pwr_key, KEY_POWER, 1);
91 input_sync(mi->pwr_key);
92 mi->pwr_key_pressed = 1;
95 case MISCEVENT_PWRONR:
96 if (mi->pwr_key_pressed) {
97 input_report_key(mi->pwr_key, KEY_POWER, 0);
98 input_sync(mi->pwr_key);
99 mi->pwr_key_pressed = 0;
105 #endif /* #ifdef CONFIG_MISC_RT5036_PWRKEY */
108 static rt_irq_handler rt_miscirq_handler[MISCEVENT_MAX] = {
109 [MISCEVENT_PWRONLP] = rt5036_general_irq_handler,
110 [MISCEVENT_PWRONSP] = rt5036_general_irq_handler,
111 [MISCEVENT_PWRONF] = rt5036_general_irq_handler,
112 [MISCEVENT_PWRONR] = rt5036_general_irq_handler,
113 [MISCEVENT_KPSHDN] = rt5036_general_irq_handler,
114 [MISCEVENT_VDDALV] = rt5036_general_irq_handler,
115 [MISCEVNET_OTM] = rt5036_general_irq_handler,
116 [MISCEVENT_PMICSYSLV] = rt5036_general_irq_handler,
117 [MISCEVENT_LSW2LV] = rt5036_general_irq_handler,
118 [MISCEVENT_LSW1LV] = rt5036_general_irq_handler,
119 [MISCEVENT_LDO4LV] = rt5036_general_irq_handler,
120 [MISCEVENT_LDO3LV] = rt5036_general_irq_handler,
121 [MISCEVENT_LDO2LV] = rt5036_general_irq_handler,
122 [MISCEVENT_LDO1LV] = rt5036_general_irq_handler,
123 [MISCEVENT_BUCK4LV] = rt5036_general_irq_handler,
124 [MISCEVENT_BUCK3LV] = rt5036_general_irq_handler,
125 [MISCEVENT_BUCK2LV] = rt5036_general_irq_handler,
126 [MISCEVENT_BUCK1LV] = rt5036_general_irq_handler,
129 void rt5036_misc_irq_handler(struct rt5036_misc_info *mi, unsigned int irqevent)
132 unsigned int masked_irq_event =
133 (misc_init_regval[6] << 16) | (misc_init_regval[7] << 8) |
135 unsigned int final_irq_event = irqevent & (~masked_irq_event);
137 for (i = 0; i < MISCEVENT_MAX; i++) {
138 if ((final_irq_event & (1 << i)) && rt_miscirq_handler[i])
139 rt_miscirq_handler[i] (mi, i);
142 EXPORT_SYMBOL(rt5036_misc_irq_handler);
144 static int rt5036_misc_reginit(struct i2c_client *i2c)
146 rt5036_reg_write(i2c, RT5036_REG_MISC6, misc_init_regval[5]);
147 rt5036_reg_block_write(i2c, RT5036_REG_MISC1, 5, misc_init_regval);
148 rt5036_reg_block_write(i2c, RT5036_REG_BUCKLDOIRQMASK,
149 3, &misc_init_regval[6]);
150 /*always clear at the first time*/
151 rt5036_reg_read(i2c, RT5036_REG_BUCKLDOIRQ);
152 rt5036_reg_read(i2c, RT5036_REG_LSWBASEIRQ);
153 rt5036_reg_read(i2c, RT5036_REG_PWRKEYIRQ);
157 static int rt_parse_dt(struct rt5036_misc_info *mi,
161 struct device_node *np = dev->of_node;
164 if (of_property_read_u32(np, "rt,shdn_press", &val)) {
166 "no shut_lpress property, use the default value\n");
168 if (val > RT5036_SHDNPRESS_MASK)
169 val = RT5036_SHDNPRESS_MAX;
170 misc_init_regval[1] &= (~RT5036_SHDNPRESS_MASK);
171 misc_init_regval[1] |= (val << RT5036_SHDNPRESS_SHIFT);
174 if (of_property_read_u32(np, "rt,stb_en", &val)) {
175 dev_info(dev, "no stb_en prpperty , use the default value\n");
177 if (val > RT5036_STB_MAX)
178 val = RT5036_STB_MAX;
179 misc_init_regval[2] &= (~RT5036_STBEN_MASK);
180 misc_init_regval[2] |= (val << RT5036_STBEN_SHIFT);
183 if (of_property_read_bool(np, "rt,lp_enshdn"))
184 misc_init_regval[4] |= RT5036_LPSHDNEN_MASK;
186 misc_init_regval[4] &= (~RT5036_LPSHDNEN_MASK);
188 if (of_property_read_u32(np, "rt,vsysuvlo", &val)) {
189 dev_info(dev, "no vsysuvlo prpperty , use the default value\n");
191 if (val > RT5036_SYSLV_MAX)
192 val = RT5036_SYSLV_MAX;
193 misc_init_regval[5] &= (~RT5036_SYSUVLO_MASK);
194 misc_init_regval[5] |= (val << RT5036_SYSUVLO_SHIFT);
197 if (of_property_read_bool(np, "rt,syslv_enshdn"))
198 misc_init_regval[4] |= RT5036_SYSLVENSHDN_MASK;
200 misc_init_regval[4] &= (~RT5036_SYSLVENSHDN_MASK);
202 rt_pm_off = of_property_read_bool(np, "rt,system-power-controller");
203 #endif /* #ifdef CONFIG_OF */
204 rt5036_misc_reginit(mi->i2c);
209 static int rt_parse_pdata(struct rt5036_misc_info *mi,
212 struct rt5036_misc_data *misc_pdata = dev->platform_data;
213 /*SHDN_PRESS_TIME property*/
214 misc_init_regval[1] &= (~RT5036_SHDNPRESS_MASK);
215 misc_init_regval[1] |=
216 (misc_pdata->shdn_press << RT5036_SHDNPRESS_SHIFT);
218 misc_init_regval[2] &= (~RT5036_STBEN_MASK);
219 misc_init_regval[2] |= (misc_pdata->stb_en << RT5036_STBEN_SHIFT);
220 /*LP_ENSHEN property*/
221 if (misc_pdata->lp_enshdn)
222 misc_init_regval[4] |= RT5036_LPSHDNEN_MASK;
224 misc_init_regval[4] &= (~RT5036_LPSHDNEN_MASK);
226 misc_init_regval[5] &= (~RT5036_SYSUVLO_MASK);
227 misc_init_regval[5] |= (misc_pdata->vsysuvlo << RT5036_SYSUVLO_SHIFT);
229 if (misc_pdata->syslv_enshdn)
230 misc_init_regval[4] |= RT5036_SYSLVENSHDN_MASK;
232 misc_init_regval[4] &= (~RT5036_SYSLVENSHDN_MASK);
234 rt5036_misc_reginit(mi->i2c);
239 static int rt5036_misc_probe(struct platform_device *pdev)
241 struct rt5036_chip *chip = dev_get_drvdata(pdev->dev.parent);
242 struct rt5036_platform_data *pdata = (pdev->dev.parent)->platform_data;
243 struct rt5036_misc_info *mi;
244 bool use_dt = pdev->dev.of_node;
246 mi = devm_kzalloc(&pdev->dev, sizeof(*mi), GFP_KERNEL);
252 rt_parse_dt(mi, &pdev->dev);
256 pdev->dev.platform_data = pdata->misc_pdata;
257 rt_parse_pdata(mi, &pdev->dev);
259 #ifdef CONFIG_MISC_RT5036_PWRKEY
260 mi->pwr_key = input_allocate_device();
262 dev_err(&pdev->dev, "Allocate pwr_key input fail\n");
265 input_set_capability(mi->pwr_key, EV_KEY, KEY_POWER);
266 mi->pwr_key->name = "rt5036_pwr_key";
267 mi->pwr_key->phys = "rt5036_pwr_key/input0";
268 mi->pwr_key->dev.parent = &pdev->dev;
269 if (input_register_device(mi->pwr_key)) {
270 dev_err(&pdev->dev, "register pwr key fail\n");
273 #endif /* #ifdef CONFIG_MISC_RT5036_PWRKEY */
274 mi->dev = &pdev->dev;
276 chip->misc_info = mi;
277 platform_set_drvdata(pdev, mi);
279 if (rt_pm_off && !pm_power_off)
280 pm_power_off = rt5036_chip_shutdown;
282 dev_info(&pdev->dev, "driver successfully loaded\n");
284 #ifdef CONFIG_MISC_RT5036_PWRKEY
286 input_free_device(mi->pwr_key);
287 #endif /* #ifdef CONFIG_MISC_RT5036_PWRKEY */
292 static int rt5036_misc_remove(struct platform_device *pdev)
294 #ifdef CONFIG_MISC_RT5036_PWRKEY
295 struct rt5036_misc_info *mi = platform_get_drvdata(pdev);
297 input_unregister_device(mi->pwr_key);
298 input_free_device(mi->pwr_key);
299 #endif /* #ifdef CONFIG_MISC_RT5036_PWRKEY */
303 static const struct of_device_id rt_match_table[] = {
304 {.compatible = "rt,rt5036-misc",},
308 static struct platform_driver rt5036_misc_driver = {
310 .name = RT5036_DEV_NAME "-misc",
311 .owner = THIS_MODULE,
312 .of_match_table = rt_match_table,
314 .probe = rt5036_misc_probe,
315 .remove = rt5036_misc_remove,
318 static int __init rt5036_misc_init(void)
320 return platform_driver_register(&rt5036_misc_driver);
322 subsys_initcall(rt5036_misc_init);
324 static void __exit rt5036_misc_exit(void)
326 platform_driver_unregister(&rt5036_misc_driver);
328 module_exit(rt5036_misc_exit);
330 MODULE_LICENSE("GPL");
331 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
332 MODULE_DESCRIPTION("Misc driver for RT5036");
333 MODULE_ALIAS("platform:" RT5036_DEV_NAME "-misc");
334 MODULE_VERSION(RT5036_DRV_VER);