Merge tag 'stable/for-linus-3.7-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / extcon / extcon-max8997.c
1 /*
2  * extcon-max8997.c - MAX8997 extcon driver to support MAX8997 MUIC
3  *
4  *  Copyright (C) 2012 Samsung Electrnoics
5  *  Donggeun Kim <dg77.kim@samsung.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/i2c.h>
21 #include <linux/slab.h>
22 #include <linux/interrupt.h>
23 #include <linux/err.h>
24 #include <linux/platform_device.h>
25 #include <linux/kobject.h>
26 #include <linux/mfd/max8997.h>
27 #include <linux/mfd/max8997-private.h>
28 #include <linux/extcon.h>
29 #include <linux/irqdomain.h>
30
31 #define DEV_NAME                        "max8997-muic"
32
33 /* MAX8997-MUIC STATUS1 register */
34 #define STATUS1_ADC_SHIFT               0
35 #define STATUS1_ADCLOW_SHIFT            5
36 #define STATUS1_ADCERR_SHIFT            6
37 #define STATUS1_ADC_MASK                (0x1f << STATUS1_ADC_SHIFT)
38 #define STATUS1_ADCLOW_MASK             (0x1 << STATUS1_ADCLOW_SHIFT)
39 #define STATUS1_ADCERR_MASK             (0x1 << STATUS1_ADCERR_SHIFT)
40
41 /* MAX8997-MUIC STATUS2 register */
42 #define STATUS2_CHGTYP_SHIFT            0
43 #define STATUS2_CHGDETRUN_SHIFT         3
44 #define STATUS2_DCDTMR_SHIFT            4
45 #define STATUS2_DBCHG_SHIFT             5
46 #define STATUS2_VBVOLT_SHIFT            6
47 #define STATUS2_CHGTYP_MASK             (0x7 << STATUS2_CHGTYP_SHIFT)
48 #define STATUS2_CHGDETRUN_MASK          (0x1 << STATUS2_CHGDETRUN_SHIFT)
49 #define STATUS2_DCDTMR_MASK             (0x1 << STATUS2_DCDTMR_SHIFT)
50 #define STATUS2_DBCHG_MASK              (0x1 << STATUS2_DBCHG_SHIFT)
51 #define STATUS2_VBVOLT_MASK             (0x1 << STATUS2_VBVOLT_SHIFT)
52
53 /* MAX8997-MUIC STATUS3 register */
54 #define STATUS3_OVP_SHIFT               2
55 #define STATUS3_OVP_MASK                (0x1 << STATUS3_OVP_SHIFT)
56
57 /* MAX8997-MUIC CONTROL1 register */
58 #define COMN1SW_SHIFT                   0
59 #define COMP2SW_SHIFT                   3
60 #define COMN1SW_MASK                    (0x7 << COMN1SW_SHIFT)
61 #define COMP2SW_MASK                    (0x7 << COMP2SW_SHIFT)
62 #define SW_MASK                         (COMP2SW_MASK | COMN1SW_MASK)
63
64 #define MAX8997_SW_USB          ((1 << COMP2SW_SHIFT) | (1 << COMN1SW_SHIFT))
65 #define MAX8997_SW_AUDIO        ((2 << COMP2SW_SHIFT) | (2 << COMN1SW_SHIFT))
66 #define MAX8997_SW_UART         ((3 << COMP2SW_SHIFT) | (3 << COMN1SW_SHIFT))
67 #define MAX8997_SW_OPEN         ((0 << COMP2SW_SHIFT) | (0 << COMN1SW_SHIFT))
68
69 #define MAX8997_ADC_GROUND              0x00
70 #define MAX8997_ADC_MHL                 0x01
71 #define MAX8997_ADC_JIG_USB_1           0x18
72 #define MAX8997_ADC_JIG_USB_2           0x19
73 #define MAX8997_ADC_DESKDOCK            0x1a
74 #define MAX8997_ADC_JIG_UART            0x1c
75 #define MAX8997_ADC_CARDOCK             0x1d
76 #define MAX8997_ADC_OPEN                0x1f
77
78 struct max8997_muic_irq {
79         unsigned int irq;
80         const char *name;
81         unsigned int virq;
82 };
83
84 static struct max8997_muic_irq muic_irqs[] = {
85         { MAX8997_MUICIRQ_ADCError, "muic-ADC_error" },
86         { MAX8997_MUICIRQ_ADCLow, "muic-ADC_low" },
87         { MAX8997_MUICIRQ_ADC, "muic-ADC" },
88         { MAX8997_MUICIRQ_VBVolt, "muic-VB_voltage" },
89         { MAX8997_MUICIRQ_DBChg, "muic-DB_charger" },
90         { MAX8997_MUICIRQ_DCDTmr, "muic-DCD_timer" },
91         { MAX8997_MUICIRQ_ChgDetRun, "muic-CDR_status" },
92         { MAX8997_MUICIRQ_ChgTyp, "muic-charger_type" },
93         { MAX8997_MUICIRQ_OVP, "muic-over_voltage" },
94 };
95
96 struct max8997_muic_info {
97         struct device *dev;
98         struct i2c_client *muic;
99         struct max8997_muic_platform_data *muic_pdata;
100
101         int irq;
102         struct work_struct irq_work;
103
104         enum max8997_muic_charger_type pre_charger_type;
105         int pre_adc;
106
107         struct mutex mutex;
108
109         struct extcon_dev       *edev;
110 };
111
112 const char *max8997_extcon_cable[] = {
113         [0] = "USB",
114         [1] = "USB-Host",
115         [2] = "TA",
116         [3] = "Fast-charger",
117         [4] = "Slow-charger",
118         [5] = "Charge-downstream",
119         [6] = "MHL",
120         [7] = "Dock-desk",
121         [8] = "Dock-card",
122         [9] = "JIG",
123
124         NULL,
125 };
126
127 static int max8997_muic_handle_usb(struct max8997_muic_info *info,
128                         enum max8997_muic_usb_type usb_type, bool attached)
129 {
130         int ret = 0;
131
132         if (usb_type == MAX8997_USB_HOST) {
133                 /* switch to USB */
134                 ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
135                                 attached ? MAX8997_SW_USB : MAX8997_SW_OPEN,
136                                 SW_MASK);
137                 if (ret) {
138                         dev_err(info->dev, "failed to update muic register\n");
139                         goto out;
140                 }
141         }
142
143         switch (usb_type) {
144         case MAX8997_USB_HOST:
145                 extcon_set_cable_state(info->edev, "USB-Host", attached);
146                 break;
147         case MAX8997_USB_DEVICE:
148                 extcon_set_cable_state(info->edev, "USB", attached);
149                 break;
150         default:
151                 ret = -EINVAL;
152                 break;
153         }
154
155 out:
156         return ret;
157 }
158
159 static int max8997_muic_handle_dock(struct max8997_muic_info *info,
160                         int adc, bool attached)
161 {
162         int ret = 0;
163
164         /* switch to AUDIO */
165         ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
166                                 attached ? MAX8997_SW_AUDIO : MAX8997_SW_OPEN,
167                                 SW_MASK);
168         if (ret) {
169                 dev_err(info->dev, "failed to update muic register\n");
170                 goto out;
171         }
172
173         switch (adc) {
174         case MAX8997_ADC_DESKDOCK:
175                 extcon_set_cable_state(info->edev, "Dock-desk", attached);
176                 break;
177         case MAX8997_ADC_CARDOCK:
178                 extcon_set_cable_state(info->edev, "Dock-card", attached);
179                 break;
180         default:
181                 ret = -EINVAL;
182                 break;
183         }
184 out:
185         return ret;
186 }
187
188 static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info,
189                         bool attached)
190 {
191         int ret = 0;
192
193         /* switch to UART */
194         ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
195                                 attached ? MAX8997_SW_UART : MAX8997_SW_OPEN,
196                                 SW_MASK);
197         if (ret) {
198                 dev_err(info->dev, "failed to update muic register\n");
199                 goto out;
200         }
201
202         extcon_set_cable_state(info->edev, "JIG", attached);
203 out:
204         return ret;
205 }
206
207 static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info)
208 {
209         int ret = 0;
210
211         switch (info->pre_adc) {
212         case MAX8997_ADC_GROUND:
213                 ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false);
214                 break;
215         case MAX8997_ADC_MHL:
216                 extcon_set_cable_state(info->edev, "MHL", false);
217                 break;
218         case MAX8997_ADC_JIG_USB_1:
219         case MAX8997_ADC_JIG_USB_2:
220                 ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, false);
221                 break;
222         case MAX8997_ADC_DESKDOCK:
223         case MAX8997_ADC_CARDOCK:
224                 ret = max8997_muic_handle_dock(info, info->pre_adc, false);
225                 break;
226         case MAX8997_ADC_JIG_UART:
227                 ret = max8997_muic_handle_jig_uart(info, false);
228                 break;
229         default:
230                 break;
231         }
232
233         return ret;
234 }
235
236 static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc)
237 {
238         int ret = 0;
239
240         switch (adc) {
241         case MAX8997_ADC_GROUND:
242                 ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true);
243                 break;
244         case MAX8997_ADC_MHL:
245                 extcon_set_cable_state(info->edev, "MHL", true);
246                 break;
247         case MAX8997_ADC_JIG_USB_1:
248         case MAX8997_ADC_JIG_USB_2:
249                 ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, true);
250                 break;
251         case MAX8997_ADC_DESKDOCK:
252         case MAX8997_ADC_CARDOCK:
253                 ret = max8997_muic_handle_dock(info, adc, true);
254                 break;
255         case MAX8997_ADC_JIG_UART:
256                 ret = max8997_muic_handle_jig_uart(info, true);
257                 break;
258         case MAX8997_ADC_OPEN:
259                 ret = max8997_muic_handle_adc_detach(info);
260                 break;
261         default:
262                 ret = -EINVAL;
263                 goto out;
264         }
265
266         info->pre_adc = adc;
267 out:
268         return ret;
269 }
270
271 static int max8997_muic_handle_charger_type_detach(
272                                 struct max8997_muic_info *info)
273 {
274         switch (info->pre_charger_type) {
275         case MAX8997_CHARGER_TYPE_USB:
276                 extcon_set_cable_state(info->edev, "USB", false);
277                 break;
278         case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
279                 extcon_set_cable_state(info->edev, "Charge-downstream", false);
280                 break;
281         case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
282                 extcon_set_cable_state(info->edev, "TA", false);
283                 break;
284         case MAX8997_CHARGER_TYPE_500MA:
285                 extcon_set_cable_state(info->edev, "Slow-charger", false);
286                 break;
287         case MAX8997_CHARGER_TYPE_1A:
288                 extcon_set_cable_state(info->edev, "Fast-charger", false);
289                 break;
290         default:
291                 return -EINVAL;
292                 break;
293         }
294
295         return 0;
296 }
297
298 static int max8997_muic_handle_charger_type(struct max8997_muic_info *info,
299                                 enum max8997_muic_charger_type charger_type)
300 {
301         u8 adc;
302         int ret;
303
304         ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_STATUS1, &adc);
305         if (ret) {
306                 dev_err(info->dev, "failed to read muic register\n");
307                 goto out;
308         }
309
310         switch (charger_type) {
311         case MAX8997_CHARGER_TYPE_NONE:
312                 ret = max8997_muic_handle_charger_type_detach(info);
313                 break;
314         case MAX8997_CHARGER_TYPE_USB:
315                 if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) {
316                         max8997_muic_handle_usb(info,
317                                         MAX8997_USB_DEVICE, true);
318                 }
319                 break;
320         case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
321                 extcon_set_cable_state(info->edev, "Charge-downstream", true);
322                 break;
323         case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
324                 extcon_set_cable_state(info->edev, "TA", true);
325                 break;
326         case MAX8997_CHARGER_TYPE_500MA:
327                 extcon_set_cable_state(info->edev, "Slow-charger", true);
328                 break;
329         case MAX8997_CHARGER_TYPE_1A:
330                 extcon_set_cable_state(info->edev, "Fast-charger", true);
331                 break;
332         default:
333                 ret = -EINVAL;
334                 goto out;
335         }
336
337         info->pre_charger_type = charger_type;
338 out:
339         return ret;
340 }
341
342 static void max8997_muic_irq_work(struct work_struct *work)
343 {
344         struct max8997_muic_info *info = container_of(work,
345                         struct max8997_muic_info, irq_work);
346         u8 status[2];
347         u8 adc, chg_type;
348         int irq_type = 0;
349         int i, ret;
350
351         mutex_lock(&info->mutex);
352
353         ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
354                                 2, status);
355         if (ret) {
356                 dev_err(info->dev, "failed to read muic register\n");
357                 mutex_unlock(&info->mutex);
358                 return;
359         }
360
361         dev_dbg(info->dev, "%s: STATUS1:0x%x, 2:0x%x\n", __func__,
362                         status[0], status[1]);
363
364         for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
365                 if (info->irq == muic_irqs[i].virq)
366                         irq_type = muic_irqs[i].irq;
367
368         switch (irq_type) {
369         case MAX8997_MUICIRQ_ADC:
370                 adc = status[0] & STATUS1_ADC_MASK;
371                 adc >>= STATUS1_ADC_SHIFT;
372
373                 max8997_muic_handle_adc(info, adc);
374                 break;
375         case MAX8997_MUICIRQ_ChgTyp:
376                 chg_type = status[1] & STATUS2_CHGTYP_MASK;
377                 chg_type >>= STATUS2_CHGTYP_SHIFT;
378
379                 max8997_muic_handle_charger_type(info, chg_type);
380                 break;
381         default:
382                 dev_info(info->dev, "misc interrupt: irq %d occurred\n",
383                                 irq_type);
384                 break;
385         }
386
387         mutex_unlock(&info->mutex);
388
389         return;
390 }
391
392 static irqreturn_t max8997_muic_irq_handler(int irq, void *data)
393 {
394         struct max8997_muic_info *info = data;
395
396         dev_dbg(info->dev, "irq:%d\n", irq);
397         info->irq = irq;
398
399         schedule_work(&info->irq_work);
400
401         return IRQ_HANDLED;
402 }
403
404 static void max8997_muic_detect_dev(struct max8997_muic_info *info)
405 {
406         int ret;
407         u8 status[2], adc, chg_type;
408
409         ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
410                                 2, status);
411         if (ret) {
412                 dev_err(info->dev, "failed to read muic register\n");
413                 return;
414         }
415
416         dev_info(info->dev, "STATUS1:0x%x, STATUS2:0x%x\n",
417                         status[0], status[1]);
418
419         adc = status[0] & STATUS1_ADC_MASK;
420         adc >>= STATUS1_ADC_SHIFT;
421
422         chg_type = status[1] & STATUS2_CHGTYP_MASK;
423         chg_type >>= STATUS2_CHGTYP_SHIFT;
424
425         max8997_muic_handle_adc(info, adc);
426         max8997_muic_handle_charger_type(info, chg_type);
427 }
428
429 static int __devinit max8997_muic_probe(struct platform_device *pdev)
430 {
431         struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent);
432         struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev);
433         struct max8997_muic_info *info;
434         int ret, i;
435
436         info = kzalloc(sizeof(struct max8997_muic_info), GFP_KERNEL);
437         if (!info) {
438                 dev_err(&pdev->dev, "failed to allocate memory\n");
439                 ret = -ENOMEM;
440                 goto err_kfree;
441         }
442
443         info->dev = &pdev->dev;
444         info->muic = max8997->muic;
445
446         platform_set_drvdata(pdev, info);
447         mutex_init(&info->mutex);
448
449         INIT_WORK(&info->irq_work, max8997_muic_irq_work);
450
451         for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
452                 struct max8997_muic_irq *muic_irq = &muic_irqs[i];
453                 int virq = 0;
454
455                 virq = irq_create_mapping(max8997->irq_domain, muic_irq->irq);
456                 if (!virq)
457                         goto err_irq;
458                 muic_irq->virq = virq;
459
460                 ret = request_threaded_irq(virq, NULL,max8997_muic_irq_handler,
461                                 0, muic_irq->name, info);
462                 if (ret) {
463                         dev_err(&pdev->dev,
464                                 "failed: irq request (IRQ: %d,"
465                                 " error :%d)\n",
466                                 muic_irq->irq, ret);
467                         goto err_irq;
468                 }
469         }
470
471         /* External connector */
472         info->edev = kzalloc(sizeof(struct extcon_dev), GFP_KERNEL);
473         if (!info->edev) {
474                 dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
475                 ret = -ENOMEM;
476                 goto err_irq;
477         }
478         info->edev->name = DEV_NAME;
479         info->edev->supported_cable = max8997_extcon_cable;
480         ret = extcon_dev_register(info->edev, NULL);
481         if (ret) {
482                 dev_err(&pdev->dev, "failed to register extcon device\n");
483                 goto err_extcon;
484         }
485
486         /* Initialize registers according to platform data */
487         if (pdata->muic_pdata) {
488                 struct max8997_muic_platform_data *mdata = info->muic_pdata;
489
490                 for (i = 0; i < mdata->num_init_data; i++) {
491                         max8997_write_reg(info->muic, mdata->init_data[i].addr,
492                                         mdata->init_data[i].data);
493                 }
494         }
495
496         /* Initial device detection */
497         max8997_muic_detect_dev(info);
498
499         return ret;
500
501 err_extcon:
502         kfree(info->edev);
503 err_irq:
504         while (--i >= 0)
505                 free_irq(muic_irqs[i].virq, info);
506         kfree(info);
507 err_kfree:
508         return ret;
509 }
510
511 static int __devexit max8997_muic_remove(struct platform_device *pdev)
512 {
513         struct max8997_muic_info *info = platform_get_drvdata(pdev);
514         int i;
515
516         for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
517                 free_irq(muic_irqs[i].virq, info);
518         cancel_work_sync(&info->irq_work);
519
520         extcon_dev_unregister(info->edev);
521
522         kfree(info->edev);
523         kfree(info);
524
525         return 0;
526 }
527
528 static struct platform_driver max8997_muic_driver = {
529         .driver         = {
530                 .name   = DEV_NAME,
531                 .owner  = THIS_MODULE,
532         },
533         .probe          = max8997_muic_probe,
534         .remove         = __devexit_p(max8997_muic_remove),
535 };
536
537 module_platform_driver(max8997_muic_driver);
538
539 MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver");
540 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
541 MODULE_LICENSE("GPL");