drivers:misc: Setup gamepad_reset gpio only on loki
[linux-3.10.git] / drivers / misc / max77660-sim.c
1 /*
2  * MAXIM MAX77660 SIM driver
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
5  * Author: Shawn joo <sjoo@nvidia.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU General Public License,
9  * version 2, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/debugfs.h>
21 #include <linux/errno.h>
22 #include <linux/gpio.h>
23 #include <linux/interrupt.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/mfd/max77660/max77660-core.h>
27 #include <linux/of_device.h>
28 #include <linux/platform_device.h>
29 #include <linux/seq_file.h>
30 #include <linux/miscdevice.h>
31
32 struct max77660_sim {
33         struct device           *parent;
34         struct device           *dev;
35         struct device           *miscdev;
36         int sim_irq;
37         bool sim1_insert;
38         bool sim2_insert;
39 };
40
41 static ssize_t max77660_sim1_state_read(struct device *dev,
42                 struct device_attribute *attr, char *buf)
43 {
44         struct platform_device *device = to_platform_device(dev);
45         struct max77660_sim *sim = dev_get_platdata(&device->dev);
46
47         return sprintf(buf, "%s\n", sim->sim1_insert ? "1" : "0");
48 }
49
50 static DEVICE_ATTR(sim1_inserted, S_IRUSR,
51                 max77660_sim1_state_read, NULL);
52
53 static ssize_t max77660_sim2_state_read(struct device *dev,
54                 struct device_attribute *attr, char *buf)
55 {
56         struct platform_device *device = to_platform_device(dev);
57         struct max77660_sim *sim = dev_get_platdata(&device->dev);
58
59
60         return sprintf(buf, "%s\n", sim->sim2_insert ? "1" : "0");
61 }
62
63 static DEVICE_ATTR(sim2_inserted, S_IRUSR,
64                 max77660_sim2_state_read, NULL);
65
66 static struct attribute *sim_attrs[] = {
67         &dev_attr_sim1_inserted.attr,
68         &dev_attr_sim2_inserted.attr,
69         NULL
70 };
71
72 static const struct attribute_group sim_attr_group = {
73         .attrs = sim_attrs,
74 };
75
76
77 static irqreturn_t max77660_sim_irq(int irq, void *data)
78 {
79         struct max77660_sim *sim = data;
80         u8 val, val2;
81         int ret, ret2;
82         bool sim1 = sim->sim1_insert;
83         bool sim2 = sim->sim2_insert;
84
85         ret = max77660_reg_read(sim->parent, MAX77660_PWR_SLAVE,
86                                 MAX77660_REG_SIM1INT, &val);
87         ret2 = max77660_reg_read(sim->parent, MAX77660_PWR_SLAVE,
88                                 MAX77660_REG_SIM1STAT, &val2);
89
90         if (ret || ret2)
91                 dev_err(sim->dev, "sim1 reg read fails. ret(%d, %d)\n",
92                                 ret, ret2);
93         else if (val & BIT(0) && val2 & BIT(0))
94                 sim1 = true;
95         else if (val & BIT(1) && !(val2 & BIT(0)))
96                 sim1 = false;
97
98
99         ret = max77660_reg_read(sim->parent, MAX77660_PWR_SLAVE,
100                                 MAX77660_REG_SIM2INT, &val);
101         ret2 = max77660_reg_read(sim->parent, MAX77660_PWR_SLAVE,
102                                 MAX77660_REG_SIM2STAT, &val2);
103
104         if (ret || ret2)
105                 dev_err(sim->dev, "sim2 reg read fails. ret(%d, %d)\n",
106                                 ret, ret2);
107         if (val & BIT(0) && val2 & BIT(0))
108                 sim2 = true;
109         else if (val & BIT(1) && !(val2 & BIT(0)))
110                 sim2 = false;
111
112         if (sim1 != sim->sim1_insert) {
113                 sim->sim1_insert = sim1;
114                 sysfs_notify(&sim->miscdev->kobj, NULL, "sim1_inserted");
115                 dev_dbg(sim->dev, "sim1(%s)\n", sim1 ? "insert" : "removal");
116         }
117         if (sim2 != sim->sim2_insert) {
118                 sim->sim2_insert = sim2;
119                 sysfs_notify(&sim->miscdev->kobj, NULL, "sim2_inserted");
120                 dev_dbg(sim->dev, "sim2(%s)\n", sim2 ? "insert" : "removal");
121         }
122
123         return IRQ_HANDLED;
124 }
125
126 static struct miscdevice sim_miscdev = {
127         .minor = MISC_DYNAMIC_MINOR,
128         .name = "sim",
129 };
130
131 static int max77660_sim_probe(struct platform_device *pdev)
132 {
133         struct max77660_platform_data *pdata;
134         struct max77660_sim *sim;
135         int ret, val;
136         int sim_irq;
137         struct max77660_sim_platform_data *sim_pdata;
138         struct platform_device *misc_pdev;
139
140         pdata = dev_get_platdata(pdev->dev.parent);
141         if (!pdata) {
142                 dev_err(&pdev->dev, "Platform data not found\n");
143                 return -ENODEV;
144         }
145
146         sim_pdata = pdata->sim_pdata;
147
148         sim_irq = platform_get_irq(pdev, 0);
149         if (sim_irq <= 0) {
150                 dev_err(&pdev->dev, "sim interrupt is not available\n");
151                 return -ENODEV;
152         }
153
154         /* SIM interrupt mask */
155         ret = max77660_reg_write(pdev->dev.parent, MAX77660_PWR_SLAVE,
156                         MAX77660_REG_SIM1NTM, 0x00);
157         if (ret < 0)
158                 goto err_reg_access;
159
160         ret = max77660_reg_write(pdev->dev.parent, MAX77660_PWR_SLAVE,
161                         MAX77660_REG_SIM2NTM, 0x00);
162         if (ret < 0)
163                 goto err_reg_access;
164
165         /* SIM1 config1 */
166         val = sim_pdata->sim_reg[0].detect_en << SIM_SIM1_2_CNFG1_SIM_EN_SHIFT;
167         val |= sim_pdata->sim_reg[0].batremove_en <<
168                 SIM_SIM1_2_CNFG1_BATREM_EN_SHIFT;
169         val |= sim_pdata->sim_reg[0].det_debouncecnt <<
170                 SIM_SIM1_2_CNFG1_SIMDBCNT_SHIFT;
171         ret = max77660_reg_write(pdev->dev.parent, MAX77660_PWR_SLAVE,
172                         MAX77660_REG_SIM1CNFG1, val);
173         if (ret < 0)
174                 goto err_reg_access;
175
176         /* SIM1 config2 */
177         val = sim_pdata->sim_reg[0].auto_pwrdn_en <<
178                 SIM_SIM1_2_CNFG1_SIM_PWRDEN_SHIFT;
179         val |= sim_pdata->sim_reg[0].inst_pol <<
180                 SIM_SIM1_2_CNFG1_SIMAH_SHIFT;
181         val |= sim_pdata->sim_reg[0].pwrdn_debouncecnt <<
182                 SIM_SIM1_2_CNFG1_SIMPWRDNCNT_SHIFT;
183         val |= (sim_pdata->sim_reg[0].sim_puen <<
184                 SIM_SIM1_2_CNFG1_SIM_PUEN_SHIFT);
185         ret = max77660_reg_write(pdev->dev.parent, MAX77660_PWR_SLAVE,
186                         MAX77660_REG_SIM1CNFG2, val);
187         if (ret < 0)
188                 goto err_reg_access;
189
190         /* SIM2 config1 */
191         val = sim_pdata->sim_reg[1].detect_en << SIM_SIM1_2_CNFG1_SIM_EN_SHIFT;
192         val |= sim_pdata->sim_reg[1].batremove_en <<
193                 SIM_SIM1_2_CNFG1_BATREM_EN_SHIFT;
194         val |= sim_pdata->sim_reg[1].det_debouncecnt <<
195                 SIM_SIM1_2_CNFG1_SIMDBCNT_SHIFT;
196         ret = max77660_reg_write(pdev->dev.parent, MAX77660_PWR_SLAVE,
197                         MAX77660_REG_SIM2CNFG1, val);
198         if (ret < 0)
199                 goto err_reg_access;
200
201         /* SIM2 config2 */
202         val = sim_pdata->sim_reg[1].auto_pwrdn_en <<
203                 SIM_SIM1_2_CNFG1_SIM_PWRDEN_SHIFT;
204         val |= sim_pdata->sim_reg[1].inst_pol <<
205                 SIM_SIM1_2_CNFG1_SIMAH_SHIFT;
206         val |= sim_pdata->sim_reg[1].pwrdn_debouncecnt <<
207                 SIM_SIM1_2_CNFG1_SIMPWRDNCNT_SHIFT;
208         val |= (sim_pdata->sim_reg[1].sim_puen <<
209                 SIM_SIM1_2_CNFG1_SIM_PUEN_SHIFT);
210         ret = max77660_reg_write(pdev->dev.parent, MAX77660_PWR_SLAVE,
211                         MAX77660_REG_SIM2CNFG2, val);
212         if (ret < 0)
213                 goto err_reg_access;
214
215         if (misc_register(&sim_miscdev) != 0) {
216                 dev_err(&pdev->dev, "sim: cannot register miscdev\n");
217                 return -ENODEV;
218         }
219
220         if (sysfs_create_group(&sim_miscdev.this_device->kobj,
221                                 &sim_attr_group)) {
222                 dev_err(&pdev->dev, "sysfs fails\n");
223                 ret = -ENODEV;
224                 goto err_sysfs;
225         }
226
227         sim = devm_kzalloc(&pdev->dev,
228                                 sizeof(*sim), GFP_KERNEL);
229         if (!sim) {
230                 dev_err(&pdev->dev, "Could not allocate max77660_sim\n");
231                 ret = -ENOMEM;
232                 goto err_malloc;
233         }
234
235         sim->parent = pdev->dev.parent;
236         sim->dev = &pdev->dev;
237         sim->miscdev = sim_miscdev.this_device;
238         sim->sim_irq = sim_irq;
239         platform_set_drvdata(pdev, sim);
240         misc_pdev = to_platform_device(sim_miscdev.this_device);
241         misc_pdev->dev.platform_data = sim;
242
243         ret = request_threaded_irq(sim_irq, NULL,  max77660_sim_irq,
244                         IRQF_ONESHOT,
245                         "SIM_DETECT_IRQ", sim);
246         if (ret < 0) {
247                 dev_err(&pdev->dev, "sim irq fails\n");
248                 ret = -ENODEV;
249                 goto err_malloc;
250         }
251
252         return 0;
253
254 err_malloc:
255         sysfs_remove_group(&sim_miscdev.this_device->kobj, &sim_attr_group);
256 err_sysfs:
257         misc_deregister(&sim_miscdev);
258 err_reg_access:
259         dev_err(&pdev->dev, "probe fails. ret(%d)\n", ret);
260
261         return ret;
262 }
263
264 static int max77660_sim_remove(struct platform_device *pdev)
265 {
266         struct max77660_sim *sim = platform_get_drvdata(pdev);
267
268         free_irq(sim->sim_irq, sim);
269         sysfs_remove_group(&sim_miscdev.this_device->kobj, &sim_attr_group);
270         misc_deregister(&sim_miscdev);
271         return 0;
272 }
273
274 static struct platform_driver max77660_sim_driver = {
275         .driver.name    = "max77660-sim",
276         .driver.owner   = THIS_MODULE,
277         .probe          = max77660_sim_probe,
278         .remove         = max77660_sim_remove,
279 };
280
281 static int __init max77660_sim_init(void)
282 {
283         return platform_driver_register(&max77660_sim_driver);
284 }
285 subsys_initcall(max77660_sim_init);
286
287 static void __exit max77660_sim_exit(void)
288 {
289         platform_driver_unregister(&max77660_sim_driver);
290 }
291 module_exit(max77660_sim_exit);
292
293 MODULE_DESCRIPTION("sim interface for MAX77660 PMIC");
294 MODULE_VERSION("1.0");
295 MODULE_LICENSE("GPL v2");
296 MODULE_ALIAS("platform:max77660-sim");