temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / cpcap-core.c
1 /*
2  * Copyright (C) 2007-2010 Motorola, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
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.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16  * 02111-1307, USA
17  */
18
19 #include <linux/fs.h>
20 #include <linux/miscdevice.h>
21 #include <linux/platform_device.h>
22 #include <linux/regulator/machine.h>
23 #include <linux/spi/spi.h>
24 #include <linux/spi/cpcap.h>
25 #include <linux/spi/cpcap-regbits.h>
26 #include <linux/uaccess.h>
27 #include <linux/reboot.h>
28 #include <linux/notifier.h>
29 #include <linux/delay.h>
30 #include <linux/pm.h>
31
32 struct cpcap_driver_info {
33         struct list_head list;
34         struct platform_device *pdev;
35 };
36
37 static long ioctl(struct file *file, unsigned int cmd, unsigned long arg);
38 static int __devinit cpcap_probe(struct spi_device *spi);
39 static int __devexit cpcap_remove(struct spi_device *spi);
40
41 #ifdef CONFIG_PM
42 static int cpcap_suspend(struct spi_device *spi, pm_message_t mesg);
43 static int cpcap_resume(struct spi_device *spi);
44 #endif
45
46 const static struct file_operations cpcap_fops = {
47         .owner = THIS_MODULE,
48         .unlocked_ioctl = ioctl,
49 };
50
51 static struct miscdevice cpcap_dev = {
52         .minor  = MISC_DYNAMIC_MINOR,
53         .name   = CPCAP_DEV_NAME,
54         .fops   = &cpcap_fops,
55 };
56
57 static struct spi_driver cpcap_driver = {
58         .driver = {
59                    .name = "cpcap",
60                    .bus = &spi_bus_type,
61                    .owner = THIS_MODULE,
62                    },
63         .probe = cpcap_probe,
64         .remove = __devexit_p(cpcap_remove),
65 #ifdef CONFIG_PM
66         .suspend = cpcap_suspend,
67         .resume = cpcap_resume,
68 #endif
69 };
70
71 static struct platform_device cpcap_adc_device = {
72         .name           = "cpcap_adc",
73         .id             = -1,
74         .dev.platform_data = NULL,
75 };
76
77
78 static struct platform_device cpcap_key_device = {
79         .name           = "cpcap_key",
80         .id             = -1,
81         .dev.platform_data = NULL,
82 };
83
84 static struct platform_device cpcap_uc_device = {
85         .name           = "cpcap_uc",
86         .id             = -1,
87         .dev.platform_data = NULL,
88 };
89
90 static struct platform_device cpcap_rtc_device = {
91         .name           = "cpcap_rtc",
92         .id             = -1,
93         .dev.platform_data = NULL,
94 };
95
96 /* List of required CPCAP devices that will ALWAYS be present.
97  *
98  * DO NOT ADD NEW DEVICES TO THIS LIST! You must use cpcap_driver_register()
99  * for any new drivers for non-core functionality of CPCAP.
100  */
101 static struct platform_device *cpcap_devices[] = {
102         &cpcap_uc_device,
103         &cpcap_adc_device,
104         &cpcap_key_device,
105         &cpcap_rtc_device,
106 };
107
108 static struct cpcap_device *misc_cpcap;
109
110 static LIST_HEAD(cpcap_device_list);
111 static DEFINE_MUTEX(cpcap_driver_lock);
112
113 static int cpcap_reboot(struct notifier_block *this, unsigned long code,
114                         void *cmd)
115 {
116         int ret = -1;
117         int result = NOTIFY_DONE;
118
119         /* Disable the USB transceiver */
120         ret = cpcap_regacc_write(misc_cpcap, CPCAP_REG_USBC2, 0,
121                                  CPCAP_BIT_USBXCVREN);
122
123         if (ret) {
124                 dev_err(&(misc_cpcap->spi->dev),
125                         "Disable Transciever failure.\n");
126                 result = NOTIFY_BAD;
127         }
128
129         if (code == SYS_RESTART)
130                 cpcap_regacc_write(misc_cpcap, CPCAP_REG_MI2, 0, 0xFFFF);
131
132         /* Always clear the power cut bit on SW Shutdown*/
133         ret = cpcap_regacc_write(misc_cpcap, CPCAP_REG_PC1,
134                 0, CPCAP_BIT_PC1_PCEN);
135         if (ret) {
136                 dev_err(&(misc_cpcap->spi->dev),
137                         "Clear Power Cut bit failure.\n");
138                 result = NOTIFY_BAD;
139         }
140
141         /* Clear the charger and charge path settings to avoid a false turn on
142          * event in caused by CPCAP. After clearing these settings, 100ms is
143          * needed to before SYSRSTRTB is pulled low to avoid the false turn on
144          * event.
145          */
146         cpcap_regacc_write(misc_cpcap, CPCAP_REG_CRM, 0, 0x3FFF);
147         mdelay(100);
148
149         return result;
150 }
151 static struct notifier_block cpcap_reboot_notifier = {
152         .notifier_call = cpcap_reboot,
153 };
154
155 static int __init cpcap_init(void)
156 {
157         return spi_register_driver(&cpcap_driver);
158 }
159
160 static void cpcap_vendor_read(struct cpcap_device *cpcap)
161 {
162         unsigned short value;
163
164         (void)cpcap_regacc_read(cpcap, CPCAP_REG_VERSC1, &value);
165
166         cpcap->vendor = (enum cpcap_vendor)((value >> 6) & 0x0007);
167         cpcap->revision = (enum cpcap_revision)(((value >> 3) & 0x0007) |
168                                                 ((value << 3) & 0x0038));
169 }
170
171
172 int cpcap_device_unregister(struct platform_device *pdev)
173 {
174         struct cpcap_driver_info *info;
175         struct cpcap_driver_info *tmp;
176         int found;
177
178
179         found = 0;
180         mutex_lock(&cpcap_driver_lock);
181
182         list_for_each_entry_safe(info, tmp, &cpcap_device_list, list) {
183                 if (info->pdev == pdev) {
184                         list_del(&info->list);
185
186                         /*
187                          * misc_cpcap != NULL suggests pdev
188                          * already registered
189                          */
190                         if (misc_cpcap) {
191                                 printk(KERN_INFO "CPCAP: unregister %s\n",
192                                         pdev->name);
193                                 platform_device_unregister(pdev);
194                         }
195                         info->pdev = NULL;
196                         kfree(info);
197                         found = 1;
198                 }
199         }
200
201         mutex_unlock(&cpcap_driver_lock);
202
203         BUG_ON(!found);
204         return 0;
205 }
206
207 int cpcap_device_register(struct platform_device *pdev)
208 {
209         int retval;
210         struct cpcap_driver_info *info;
211
212         retval = 0;
213
214         info = kzalloc(sizeof(*info), GFP_KERNEL);
215         if (!info) {
216                 printk(KERN_ERR "Cannot save device %s\n", pdev->name);
217                 return -ENOMEM;
218         }
219
220         mutex_lock(&cpcap_driver_lock);
221
222         info->pdev = pdev;
223         list_add_tail(&info->list, &cpcap_device_list);
224
225         /* If misc_cpcap is valid, the CPCAP driver has already been probed.
226          * Therefore, call platform_device_register() to probe the device.
227          */
228         if (misc_cpcap) {
229                 dev_info(&(misc_cpcap->spi->dev),
230                          "Probing CPCAP device %s\n", pdev->name);
231
232                 /*
233                  * platform_data is non-empty indicates
234                  * CPCAP client devices need to pass their own data
235                  * In that case we put cpcap data in driver_data
236                  */
237                 if (pdev->dev.platform_data != NULL)
238                         platform_set_drvdata(pdev, misc_cpcap);
239                 else
240                         pdev->dev.platform_data = misc_cpcap;
241                 retval = platform_device_register(pdev);
242         } else
243                 printk(KERN_INFO "CPCAP: delaying %s probe\n",
244                                 pdev->name);
245         mutex_unlock(&cpcap_driver_lock);
246
247         return retval;
248 }
249
250 static int __devinit cpcap_probe(struct spi_device *spi)
251 {
252         int retval = -EINVAL;
253         struct cpcap_device *cpcap;
254         struct cpcap_platform_data *data;
255         int i;
256         struct cpcap_driver_info *info;
257
258         cpcap = kzalloc(sizeof(*cpcap), GFP_KERNEL);
259         if (cpcap == NULL)
260                 return -ENOMEM;
261
262         cpcap->spi = spi;
263         data = spi->controller_data;
264         spi_set_drvdata(spi, cpcap);
265
266         retval = cpcap_regacc_init(cpcap);
267         if (retval < 0)
268                 goto free_mem;
269         retval = cpcap_irq_init(cpcap);
270         if (retval < 0)
271                 goto free_cpcap_irq;
272
273         cpcap_vendor_read(cpcap);
274
275         for (i = 0; i < ARRAY_SIZE(cpcap_devices); i++)
276                 cpcap_devices[i]->dev.platform_data = cpcap;
277
278         retval = misc_register(&cpcap_dev);
279         if (retval < 0)
280                 goto free_cpcap_irq;
281
282         /* loop twice becuase cpcap_regulator_probe may refer to other devices
283          * in this list to handle dependencies between regulators.  Create them
284          * all and then add them */
285         for (i = 0; i < CPCAP_NUM_REGULATORS; i++) {
286                 struct platform_device *pdev;
287
288                 pdev = platform_device_alloc("cpcap-regltr", i);
289                 if (!pdev) {
290                         dev_err(&(spi->dev), "Cannot create regulator\n");
291                         continue;
292                 }
293
294                 pdev->dev.parent = &(spi->dev);
295                 pdev->dev.platform_data = &data->regulator_init[i];
296                 platform_set_drvdata(pdev, cpcap);
297                 cpcap->regulator_pdev[i] = pdev;
298         }
299
300         for (i = 0; i < CPCAP_NUM_REGULATORS; i++)
301                 platform_device_add(cpcap->regulator_pdev[i]);
302
303         platform_add_devices(cpcap_devices, ARRAY_SIZE(cpcap_devices));
304
305         mutex_lock(&cpcap_driver_lock);
306         misc_cpcap = cpcap;  /* kept for misc device */
307
308         list_for_each_entry(info, &cpcap_device_list, list) {
309                 dev_info(&(spi->dev), "Probing CPCAP device %s\n",
310                          info->pdev->name);
311                 if (info->pdev->dev.platform_data != NULL)
312                         platform_set_drvdata(info->pdev, cpcap);
313                 else
314                         info->pdev->dev.platform_data = cpcap;
315                 platform_device_register(info->pdev);
316         }
317         mutex_unlock(&cpcap_driver_lock);
318
319         register_reboot_notifier(&cpcap_reboot_notifier);
320
321         return 0;
322
323 free_cpcap_irq:
324         cpcap_irq_shutdown(cpcap);
325 free_mem:
326         kfree(cpcap);
327         return retval;
328 }
329
330 static int __devexit cpcap_remove(struct spi_device *spi)
331 {
332         struct cpcap_device *cpcap = spi_get_drvdata(spi);
333         struct cpcap_driver_info *info;
334         int i;
335
336         unregister_reboot_notifier(&cpcap_reboot_notifier);
337
338         mutex_lock(&cpcap_driver_lock);
339         list_for_each_entry(info, &cpcap_device_list, list) {
340                 dev_info(&(spi->dev), "Removing CPCAP device %s\n",
341                          info->pdev->name);
342                 platform_device_unregister(info->pdev);
343         }
344         misc_cpcap = NULL;
345         mutex_unlock(&cpcap_driver_lock);
346
347         for (i = ARRAY_SIZE(cpcap_devices); i > 0; i--)
348                 platform_device_unregister(cpcap_devices[i-1]);
349
350         for (i = 0; i < CPCAP_NUM_REGULATORS; i++)
351                 platform_device_unregister(cpcap->regulator_pdev[i]);
352
353         misc_deregister(&cpcap_dev);
354         cpcap_irq_shutdown(cpcap);
355         kfree(cpcap);
356         return 0;
357 }
358
359
360 static long test_ioctl(unsigned int cmd, unsigned long arg)
361 {
362         int retval = -EINVAL;
363         struct cpcap_regacc read_data;
364         struct cpcap_regacc write_data;
365
366         switch (cmd) {
367         case CPCAP_IOCTL_TEST_READ_REG:
368                 if (copy_from_user((void *)&read_data, (void *)arg,
369                                    sizeof(read_data)))
370                         return -EFAULT;
371                 retval = cpcap_regacc_read(misc_cpcap, read_data.reg,
372                                            &read_data.value);
373                 if (retval < 0)
374                         return retval;
375                 if (copy_to_user((void *)arg, (void *)&read_data,
376                                  sizeof(read_data)))
377                         return -EFAULT;
378                 return 0;
379         break;
380
381         case CPCAP_IOCTL_TEST_WRITE_REG:
382                 if (copy_from_user((void *) &write_data,
383                                    (void *) arg,
384                                    sizeof(write_data)))
385                         return -EFAULT;
386                 retval = cpcap_regacc_write(misc_cpcap, write_data.reg,
387                                             write_data.value, write_data.mask);
388         break;
389
390         default:
391                 retval = -ENOTTY;
392         break;
393         }
394
395         return retval;
396 }
397
398 static long adc_ioctl(unsigned int cmd, unsigned long arg)
399 {
400         int retval = -EINVAL;
401         struct cpcap_adc_phase phase;
402
403         switch (cmd) {
404         case CPCAP_IOCTL_ADC_PHASE:
405                 if (copy_from_user((void *) &phase, (void *) arg,
406                                    sizeof(phase)))
407                         return -EFAULT;
408
409                 cpcap_adc_phase(misc_cpcap, &phase);
410                 retval = 0;
411         break;
412
413         default:
414                 retval = -ENOTTY;
415         break;
416         }
417
418         return retval;
419 }
420
421 static long accy_ioctl(unsigned int cmd, unsigned long arg)
422 {
423         int retval = -EINVAL;
424         struct cpcap_whisper_request read_data;
425
426         switch (cmd) {
427         case CPCAP_IOCTL_ACCY_WHISPER:
428                 if (copy_from_user((void *) &read_data, (void *) arg,
429                                    sizeof(read_data)))
430                         return -EFAULT;
431                 read_data.dock_id[CPCAP_WHISPER_ID_SIZE - 1] = '\0';
432                 read_data.dock_prop[CPCAP_WHISPER_PROP_SIZE - 1] = '\0';
433                 retval = cpcap_accy_whisper(misc_cpcap, &read_data);
434         break;
435
436         default:
437                 retval = -ENOTTY;
438         break;
439         }
440
441         return retval;
442 }
443
444 static long ioctl(struct file *file, unsigned int cmd, unsigned long arg)
445 {
446         int retval = -ENOTTY;
447         unsigned int cmd_num;
448
449         cmd_num = _IOC_NR(cmd);
450
451         if ((cmd_num > CPCAP_IOCTL_NUM_TEST__START) &&
452             (cmd_num < CPCAP_IOCTL_NUM_TEST__END)) {
453                 retval = test_ioctl(cmd, arg);
454         }
455         if ((cmd_num > CPCAP_IOCTL_NUM_ADC__START) &&
456             (cmd_num < CPCAP_IOCTL_NUM_ADC__END)) {
457                 retval = adc_ioctl(cmd, arg);
458         }
459         if ((cmd_num > CPCAP_IOCTL_NUM_ACCY__START) &&
460             (cmd_num < CPCAP_IOCTL_NUM_ACCY__END)) {
461                 retval = accy_ioctl(cmd, arg);
462         }
463
464         return retval;
465 }
466
467 static void cpcap_shutdown(void)
468 {
469         spi_unregister_driver(&cpcap_driver);
470 }
471
472 #ifdef CONFIG_PM
473 static int cpcap_suspend(struct spi_device *spi, pm_message_t mesg)
474 {
475
476         struct cpcap_device *cpcap = spi_get_drvdata(spi);
477
478         return cpcap_irq_suspend(cpcap);
479 }
480
481 static int cpcap_resume(struct spi_device *spi)
482 {
483         struct cpcap_device *cpcap = spi_get_drvdata(spi);
484
485         return cpcap_irq_resume(cpcap);
486 }
487 #endif
488
489 subsys_initcall(cpcap_init);
490 module_exit(cpcap_shutdown);
491
492 MODULE_ALIAS("platform:cpcap");
493 MODULE_DESCRIPTION("CPCAP driver");
494 MODULE_AUTHOR("Motorola");
495 MODULE_LICENSE("GPL");